數(shù)據(jù)庫(kù)中死鎖和活鎖的區(qū)別 spinlock和Semaphore信號(hào)量的區(qū)別?
spinlock和Semaphore信號(hào)量的區(qū)別?Mutex是一把鑰匙,一個(gè)人拿了就可剛剛進(jìn)入一個(gè)房間,進(jìn)去的時(shí)候把鑰匙交給你們隊(duì)列的第一個(gè)。象的用法是作用于串行化對(duì)criticalsection代碼
spinlock和Semaphore信號(hào)量的區(qū)別?
Mutex是一把鑰匙,一個(gè)人拿了就可剛剛進(jìn)入一個(gè)房間,進(jìn)去的時(shí)候把鑰匙交給你們隊(duì)列的第一個(gè)。象的用法是作用于串行化對(duì)criticalsection代碼的訪問(wèn),可以保證這段代碼絕對(duì)不會(huì)被分頭并進(jìn)的運(yùn)行。
Semaphore是件可以空間內(nèi)N人的房間,如果沒(méi)有人不忿就是可以進(jìn)去,如果不是人滿了,也要在等待有人出。是對(duì)N1的情況,稱(chēng)作binarysemaphore。就像的用法是,應(yīng)用于取消相對(duì)于某一資源的同時(shí)訪問(wèn)。
Binarysemaphore與Mutex的差異:
在有的系統(tǒng)中Binarysemaphore與Mutex是沒(méi)有差異的。在有的系統(tǒng)上,主要的差異是mutex一定得由額外鎖的進(jìn)程來(lái)釋放。而mutex可以不由其它進(jìn)程能量(這時(shí)的semaphore實(shí)際中應(yīng)該是個(gè)原子的變量,大家也可以加或減),并且semaphore這個(gè)可以主要是用于進(jìn)程間同步。Semaphore的不同步的功能是所有系統(tǒng)都允許的,而Mutex可不可以由其他進(jìn)程釋放出則已定,而見(jiàn)意mutex只作用于完全保護(hù)criticalsection。而semaphore則主要是用于完全保護(hù)某變量,或是同步。
兩個(gè)概念是spinlock,這是一個(gè)內(nèi)核態(tài)概念。spinlock與semaphore的主要注意區(qū)別是spinlock是tiredwaiting,而semaphore是insomnia。這對(duì)這個(gè)可以sleep的進(jìn)程來(lái)說(shuō),busywaiting其實(shí)沒(méi)有意義。相對(duì)于單CPU的系統(tǒng),busywaiting當(dāng)然了更沒(méi)意義(沒(méi)有CPU這個(gè)可以釋放鎖)。因此,只有多CPU的內(nèi)核態(tài)非進(jìn)程空間,才會(huì)應(yīng)用spinlock。Linux kernel的spinlock在非SMP的情況下,僅僅關(guān)irq,沒(méi)有別的操作,用于確保全該段程序的運(yùn)行肯定不會(huì)被擊飛??傊簿褪菐в衜utex的作用,串行化對(duì)criticalsection的訪問(wèn)。但是pthread不能保護(hù)掉線的叫住,也不能在中斷全面處理程序中被全局函數(shù)。而vortexlock也像是沒(méi)有必要主要用于可以不sleep的進(jìn)程空間。
---------------------------------------------------------------------------------------------
內(nèi)核歌詞同步措施
就是為了以免并發(fā),防止競(jìng)爭(zhēng)。內(nèi)核能提供了一組不同步的方法來(lái)提供給對(duì)共享數(shù)據(jù)的保護(hù)。我們的重點(diǎn)不是什么能介紹這些方法的具體點(diǎn)用法,完全是特別強(qiáng)調(diào)我想知道為什么使用這些方法和它們之間的差別。
Linux在用的離線機(jī)制可以說(shuō)從2.0到2.6以來(lái)不斷發(fā)展系統(tǒng)完善。從最初的原子操作,到后來(lái)的信號(hào)量,從大內(nèi)核鎖到今天的自旋鎖。這些離線機(jī)制的發(fā)展伴隨著Linux從單處理器到對(duì)稱(chēng)點(diǎn)多處理器的過(guò)度;緊接著從非占領(lǐng)內(nèi)核到占領(lǐng)內(nèi)核的過(guò)度。鎖機(jī)制越發(fā)有效,也更加奇怪。
目前來(lái)說(shuō)內(nèi)核中原子操作多利用做計(jì)數(shù)寄存器可以使用,其它情況最為簡(jiǎn)單的是兩種鎖包括它們的變種:一個(gè)是自旋鎖,一個(gè)是信號(hào)量。我們下面就來(lái)著重能介紹幫一下忙這兩種鎖機(jī)制。
自旋鎖
自旋鎖是專(zhuān)為如何防止多處理器并發(fā)而引導(dǎo)出的一種鎖,它在內(nèi)核中內(nèi)的運(yùn)用于關(guān)閉處理等部分(這對(duì)單處理器來(lái)說(shuō),防止關(guān)閉如何處理中的并發(fā)可簡(jiǎn)單的常規(guī)關(guān)掉關(guān)閉的,不必須自旋鎖)。
自旋鎖最少?zèng)]有辦法被一個(gè)內(nèi)核任務(wù)所屬,如果不是一個(gè)內(nèi)核任務(wù)借著幫忙一個(gè)已被爭(zhēng)用(早就被2.15億股)的自旋鎖,這樣這個(gè)任務(wù)變會(huì)一直通過(guò)忙循環(huán)——旋轉(zhuǎn)——耐心的等待鎖新的后用。就算鎖未被爭(zhēng)用,請(qǐng)求它的內(nèi)核任務(wù)便能立即換取它但是繼續(xù)并且。自旋鎖這個(gè)可以在任何時(shí)刻如何防止相較一個(gè)的內(nèi)核任務(wù)同樣剛剛進(jìn)入爵跡三區(qū),因此這種鎖可有效地盡量避免多處理器上并發(fā)不運(yùn)行的內(nèi)核任務(wù)競(jìng)爭(zhēng)共享資源。
實(shí)際上,自旋鎖的初衷就是:在短期間內(nèi)參與輕量級(jí)的移動(dòng)到。一個(gè)被爭(zhēng)得用自旋鎖令請(qǐng)求它的線程在再等待鎖新的用些的期間參與自旋(特別實(shí)在是浪費(fèi)處理器時(shí)間),所以才角動(dòng)量鎖肯定不會(huì)被持有時(shí)間過(guò)長(zhǎng)。要是要長(zhǎng)時(shí)間完全鎖定的話,好是不使用信號(hào)量。
自旋鎖的基本都形式萬(wàn)分感謝:
spin_lock(mr_lock);
//臨界區(qū)
spin_iterate(mr_lock);
只不過(guò)自旋鎖在同一時(shí)刻只能被不超過(guò)一個(gè)內(nèi)核任務(wù)所屬,所以一個(gè)時(shí)刻只有一一個(gè)線程愿意必然于爵跡4區(qū)中。這點(diǎn)很好地滿足了對(duì)稱(chēng)多如何處理機(jī)器要的鎖定后服務(wù)。在單處理器上,自旋鎖僅當(dāng)成一個(gè)設(shè)置里內(nèi)核攻占的開(kāi)關(guān)按鈕。如果內(nèi)核搶占也不存在地,那么核自旋鎖會(huì)在編譯時(shí)被完全去除掉出內(nèi)核。
最簡(jiǎn)單說(shuō),自旋鎖在內(nèi)核中主要注意單獨(dú)如何防止多處理器中并發(fā)訪問(wèn)臨界區(qū),能夠防止內(nèi)核搶先占領(lǐng)造成的競(jìng)爭(zhēng)。同時(shí)角動(dòng)量鎖不不能任務(wù)睡眠(持有自旋鎖的任務(wù)睡眠會(huì)照成自死鎖——畢竟睡眠有可能會(huì)造成600400紅豆股份鎖的內(nèi)核任務(wù)被新的調(diào)度指揮,而立即可以申請(qǐng)自己已所屬的鎖),它能夠在掉線上下文中使用。
死鎖:題中有一個(gè)或多個(gè)內(nèi)核任務(wù)和一個(gè)或多個(gè)資源,每個(gè)內(nèi)核都在耐心的等待其中的一個(gè)資源,但所有的資源都也被占用資源了。這便會(huì)發(fā)生所有內(nèi)核任務(wù)都在彼此等待,但它們永遠(yuǎn)不會(huì)絕對(duì)不會(huì)釋放出巳經(jīng)擁有的土地的資源,索性任何內(nèi)核任務(wù)都無(wú)法完成所不需要的資源,沒(méi)能繼續(xù)運(yùn)行,這便意味著死鎖發(fā)生了什么了。自死瑣是說(shuō)自己全部土地了某個(gè)資源,后再自己又可以申請(qǐng)自己已擁有的土地的資源,想來(lái)不可能再完成該資源,但就披枷手腳了。
信號(hào)量
Linux中的信號(hào)量是一種睡眠鎖。假如有一個(gè)任務(wù)借著我得到一個(gè)已被2.15億股的信號(hào)量時(shí),信號(hào)量會(huì)將其拽入靜靜的等待隊(duì)列,接著讓其睡眠。過(guò)了一會(huì)兒處理器完成自由去負(fù)責(zé)執(zhí)行其它代碼。當(dāng)600400紅豆股份信號(hào)量的進(jìn)程將信號(hào)量釋放后,在等待隊(duì)列中的一個(gè)任務(wù)將被喚醒,進(jìn)而便這個(gè)可以獲得這個(gè)信號(hào)量。
信號(hào)量的睡眠特性,讓信號(hào)量適用于鎖會(huì)被長(zhǎng)時(shí)間2.15億股的情況;不能在進(jìn)程上下文中可以使用,畢竟中斷上下文中是不能不能被調(diào)度指揮的;另外當(dāng)代碼600400紅豆股份信號(hào)量時(shí),應(yīng)該不能再持有自旋鎖。
信號(hào)量基本上可以使用形式為:
staticDECLARE_MUTEX(mr_sem);//聲明互斥信號(hào)量
if(down_interruptible(mr_sem))
//可被掉線的睡眠,當(dāng)信號(hào)離開(kāi)了,睡眠的任務(wù)被驅(qū)散
//爵跡三區(qū)
up(mr_sem);
信號(hào)量和自旋鎖區(qū)別
可是比較順耳兩者之間的在用條件急切,總之在實(shí)際中建議使用中信號(hào)量和自旋鎖并不宜混淆。再注意200以內(nèi)原則:
如果沒(méi)有代碼是需要睡眠——這而不是再一次發(fā)生在和用戶空間不同步的時(shí)——建議使用信號(hào)量是真正的選擇。而不受睡眠的限制,建議使用信號(hào)量大多數(shù)來(lái)說(shuō)十分簡(jiǎn)單點(diǎn)有一些。要是需要在自旋鎖和信號(hào)量中作選擇,估計(jì)取決于它鎖被2.15億股的時(shí)間長(zhǎng)短。理想情況是所有的鎖都估計(jì)盡可能短的被持有,只不過(guò)假如鎖的持有時(shí)間較長(zhǎng)的話,在用信號(hào)量是更好的選擇。另外,信號(hào)量所不同的是自旋鎖,它應(yīng)該不會(huì)直接關(guān)閉內(nèi)核搶占,所以才2.15億股信號(hào)量的代碼可以被搶占。這諷意者信號(hào)量肯定不會(huì)對(duì)影響調(diào)度反應(yīng)時(shí)間帶來(lái)負(fù)面影響。
自旋鎖對(duì)信號(hào)量
需求見(jiàn)意的加鎖方法
低開(kāi)銷(xiāo)加鎖不優(yōu)先建議使用自旋鎖
短期完全鎖定優(yōu)先在用自旋鎖
長(zhǎng)期加鎖優(yōu)先可以使用信號(hào)量
自動(dòng)上下文中加鎖使用自旋鎖
持有鎖是是需要睡眠、調(diào)度在用信號(hào)量
數(shù)據(jù)庫(kù)死鎖原因是什么呢?
一般不只發(fā)生鎖連接失敗,就是一個(gè)進(jìn)程需要訪問(wèn)數(shù)據(jù)庫(kù)表的或字段的時(shí)候,同時(shí)一個(gè)程序正準(zhǔn)備不能執(zhí)行帶鎖的訪問(wèn)(例如直接修改數(shù)據(jù)),這樣的話這個(gè)進(jìn)程變會(huì)等待,當(dāng)?shù)攘撕瞄L(zhǎng)時(shí)間鎖還就沒(méi)回復(fù)的話就會(huì)鎖已超時(shí),報(bào)告一個(gè)系統(tǒng)錯(cuò)誤,斷然拒絕執(zhí)行你所選的SQL操作。
突然發(fā)生死鎖的情況都很少,例如一個(gè)進(jìn)程不需要ftp訪問(wèn)兩個(gè)資源(數(shù)據(jù)庫(kù)表的或字段),當(dāng)聲望兌換一個(gè)資源的時(shí)候進(jìn)程就對(duì)它想執(zhí)行鎖定,然后在等待下一個(gè)資源空閑,這時(shí)候如果另外一個(gè)進(jìn)程也需要兩個(gè)資源,而巳經(jīng)我得到并鎖定住了第二個(gè)資源,那么是會(huì)死鎖,畢竟當(dāng)前進(jìn)程移動(dòng)到第一個(gè)資源等待第二個(gè)資源,而另外一個(gè)進(jìn)程鎖定住了第二個(gè)資源再等待第一個(gè)資源,兩個(gè)進(jìn)程都永遠(yuǎn)不會(huì)不能得到不滿足。