鎖的來(lái)由和使用
對(duì)于開(kāi)發(fā)系統(tǒng)級(jí)別軟件的朋友來(lái)說(shuō),無(wú)論你是主動(dòng)的還是被動(dòng)的,鎖的應(yīng)用都是少不了的。很多人用鎖,可是卻未必知道鎖的前世今生,什么時(shí)候用鎖,什么時(shí)候不用鎖?該用什么樣的鎖?今天我們就來(lái)對(duì)這個(gè)問(wèn)題說(shuō)道說(shuō)道。
(1)為什么用鎖?
之所以會(huì)用鎖,其根本目的在于對(duì)公共資源的保護(hù)。比如說(shuō),我們希望對(duì)某些數(shù)據(jù)的操作是連貫的、具體的。否則,如果這些臟數(shù)據(jù)如果被再次引用的話,肯定會(huì)引發(fā)不可預(yù)計(jì)的故障。雖然從代碼上看,我們的操作可能只是一條語(yǔ)句,但是它所對(duì)應(yīng)的匯編操作很有可能是由幾條命令合在一起完成的,所以中間發(fā)生任何的切換、中斷都會(huì)出現(xiàn)問(wèn)題。那么,有哪些變動(dòng)會(huì)導(dǎo)致這種情況發(fā)生呢?其實(shí)也不復(fù)雜,主要就三種,
a)中斷
b)搶占
c)smp
(2)哪些場(chǎng)景需要互斥處理?
上面說(shuō)了三種情形,其實(shí)就是代碼有可能被打擾的三種情況。首先,中斷的發(fā)生是隨機(jī)的,如果中斷中使用了和內(nèi)核段同樣的數(shù)據(jù),那么肯定會(huì)惹麻煩的。同樣,搶占也是一個(gè)很重要的問(wèn)題。所謂的搶占,其實(shí)就是說(shuō)線程在中斷返回、資源釋放、搶占點(diǎn)有可能被系統(tǒng)切換出運(yùn)行隊(duì)列。有些時(shí)候,線程的數(shù)據(jù)可能需要與另外一個(gè)線程進(jìn)行分享,如果我們此時(shí)不想和別人分享,那么關(guān)閉搶占就可以了,系統(tǒng)也不會(huì)進(jìn)行線程調(diào)度處理了。最后一種是多cpu情形,本質(zhì)上和多線程有關(guān),不同的cpu運(yùn)行不同的線程,所以對(duì)于數(shù)據(jù)的訪問(wèn)必須是互斥的,我們必須利用硬件提供的匯編語(yǔ)句來(lái)對(duì)代碼進(jìn)行互斥處理,自旋鎖就是用的最多的一種方法。
(3)有哪些鎖的使用方法?
為了提高數(shù)據(jù)的訪問(wèn)效率,人們?cè)O(shè)計(jì)了各種各樣的鎖。所有這些設(shè)計(jì)的目的只有一個(gè),就是在保持?jǐn)?shù)據(jù)正確性的條件下盡可能將鎖造成的影響降到最小。這從linux內(nèi)核發(fā)展的軌跡可以清晰地看出來(lái),越是高級(jí)的鎖,越是具有特定的應(yīng)用場(chǎng)景,越需要小心處理。就我個(gè)人了解,當(dāng)前使用較多的鎖主要有下面幾種:
a)關(guān)中斷
b)禁止搶占
c)自旋鎖
d)原子操作
e)讀寫鎖
f)互斥量
g)信號(hào)量
h)事件
(4)使用鎖需要注意些什么?
在所有代碼里面,關(guān)于多線程的編寫其實(shí)是很難的,主要是因?yàn)槎嗑€程考慮的情況多,另外一方面就是代碼調(diào)試的難度很大,所以在模塊設(shè)計(jì)的時(shí)候一定要慎重。在平時(shí)編寫的時(shí)候,多用成熟代碼,這樣才會(huì)在軟件質(zhì)量上有所保障。不過(guò),在鎖的使用中,還是有一些規(guī)則是要注意的,比如,
a)中斷的代碼是不能使用帶有schedule函數(shù)的鎖
b)搶占只能防止本cpu上線程之間的互斥
c)使用自旋鎖的代碼段不能太長(zhǎng),否則影響系統(tǒng)性能
d)互斥量只能被本線程釋放,在嵌入式實(shí)時(shí)系統(tǒng)中可能會(huì)遇到優(yōu)先級(jí)反轉(zhuǎn)的問(wèn)題
e)使用信號(hào)量最合適的地方就是pv操作
f)原子鎖計(jì)數(shù)比較合適
g)事件功能和網(wǎng)絡(luò)編程中的select很像,可以響應(yīng)多個(gè)情形,但是無(wú)法保證這些事件有序
h)鎖成對(duì)使用、有序使用,做到這些可解決一大部分的死鎖問(wèn)題
i)沒(méi)事別寫多線程,就是寫也先把單線程的代碼完善好了再進(jìn)行考慮和移植
j)在鎖中使用指針需要十分小心
posted on 2012-08-01 10:49 順其自然EVO 閱讀(202) 評(píng)論(0) 編輯 收藏 所屬分類: 數(shù)據(jù)庫(kù)