c语言中锁的作用,C语言实现原子锁(二)
我經(jīng)常在快餐廳吃飯,可以自己加飯的那種,店里有好些服務(wù)器專門負(fù)責(zé)收掉已就餐完畢的客人的餐具。但是由于客人離開座位去加飯,導(dǎo)致服務(wù)員誤收餐具的情況。所以我每次去加飯前,都會把自己的眼鏡放在菜碟旁邊,表示我還需要繼續(xù)用餐,你不要收走我的餐具_(dá)。
[TOC]
鎖與同步機(jī)制
其實上面的例子就是用來說明計算機(jī)程序中鎖是什么東東的一個很好的例子。模塊A和模塊B在某一個時刻都需要操作數(shù)據(jù)C,那么他們必須要以一種正確的方式來操作C,才能保證C不會出問題;這里的模塊A相當(dāng)于餐廳就餐中的客人,而模塊B可以看作服務(wù)員,數(shù)據(jù)C就相當(dāng)于要收拾的餐具。要保證收盤子不會出問題,我們需要一種機(jī)制——同步機(jī)制D,放置眼鏡這個事實,來使得客人和服務(wù)員正確的使用盤子,也就是正確的操作數(shù)據(jù)C同步機(jī)制是計算機(jī)編程里一個概念。我們說的“鎖”,可以是這個同步機(jī)制的別稱,也可以是實現(xiàn)同步機(jī)制的實體名稱,比如讀寫鎖和文件鎖。除了這些帶”鎖“結(jié)尾的實體,還有比如互斥量,信號,信號量,描述符IO都可以實現(xiàn)這種機(jī)制。這里的概念有些混亂,我表達(dá)得也不是很好,請大家多體會一下實體和概念的定義,這里“鎖 ”的兩個定義,就像價值和價格一樣。
鎖的本質(zhì)
鎖是同步機(jī)制的實現(xiàn),其本質(zhì)是狀態(tài)機(jī),只有狀態(tài)機(jī)在正確的狀態(tài)上才能操作數(shù)據(jù),否則就等待。下面用我們要實現(xiàn)的原子鎖模擬上鎖與解鎖的過程。模塊A與模塊B同時操作數(shù)據(jù)C,并使用原子鎖D進(jìn)行同步,設(shè)原子鎖的狀態(tài)機(jī)未鎖定狀態(tài)為0,已鎖定狀態(tài)為1,且初始狀態(tài)為0,假設(shè)時序為模塊A先通過操作鎖發(fā)起操作數(shù)據(jù)C的請求。整個操作過程的時序用以下的表格表示
時序
模塊A操作
模塊B操作
原子鎖D狀態(tài)
數(shù)據(jù)C所屬
開始
nil
nil
0
nil
A優(yōu)先B改變D的狀態(tài)
while(1){
/*it will run this code
and then break loop*/
if(D.stat==0) D.stat = 1;
if (D.stat==1) break;
}
do other something
turn stat from 0 to 1
Critical state
A操作C,B等待A再次復(fù)位D的狀態(tài)
do something to data C
while(1){
/*it will always in loop
until D's stat turn from 1 to 0*/
if(D.stat==0) D.stat = 1;
if (D.stat==1) break;
}
1
model A
A復(fù)位D的狀態(tài),B將要退出循環(huán)
D.stat = 0
while(1){/*it will break loop*/}
turn stat from 1 to 0
Critical state
B改變D的狀態(tài)
do other something
if(D.stat==0) D.stat = 1
turn stat from 0 to 1
Critical state
B操作
do other something
do something to data C
1
model B
B復(fù)位D的狀態(tài)
do other something
D.stat = 0
turn stat from 1 to 0
Critical state
結(jié)束
nil
nil
0
nil
模塊AB為了安全的操作數(shù)據(jù)C都會先改變原子鎖D的狀態(tài),如果D的狀態(tài)不符合要求就等待直到條件允許,在成功改變D的狀態(tài)后,才操作數(shù)據(jù)C,操作完畢后復(fù)位D的狀態(tài)到改變前,至此流程結(jié)束。模塊AB共同準(zhǔn)守通過鎖D對數(shù)據(jù)C進(jìn)行操作的流程規(guī)范就是一種同步機(jī)制,鎖是實現(xiàn)這個機(jī)制的手段(媒介)。任何模塊在操作數(shù)據(jù)時,只有大家都準(zhǔn)守這個同步機(jī)制,數(shù)據(jù)才不會發(fā)生混亂,否則數(shù)據(jù)就會出現(xiàn)一致性錯誤。比如還是以餐廳就餐的問題做比喻,如果我用眼鏡提示服務(wù)員不要收走我的餐具,但是他對這個嗤之以鼻,他還是可以收走我的餐具,我對此卻毫無辦法。
為何會發(fā)生同步問題
其主要原因就是需要“同時”操作數(shù)據(jù)。從就餐問題可以看出,如果服務(wù)員收盤子和我去加飯不是同時發(fā)生,就不會出現(xiàn)誤收餐具的事情,當(dāng)然不排除服務(wù)員因為不滿意老板發(fā)的薪水,故意當(dāng)客人的面就把餐具沒收的情況。所以如果不是多線程程序,絕大多數(shù)都不需要同步機(jī)制的,但不排除信號中斷也會在單進(jìn)程產(chǎn)生同步問題,還有協(xié)程機(jī)制也會,雖然他不是絕對定義上的同時操作,后面的文章會一一舉例這些情況。
臨界點
當(dāng)操作者開始改變數(shù)據(jù)的那一個時間點,就是臨界點。如果有多個操作者在這個點操作數(shù)據(jù),那么這就可能會發(fā)生數(shù)據(jù)一致性錯誤,那么這個零界點就是需要保護(hù)的臨界點。在餐廳問題中,我離開打飯,而服務(wù)員要收走餐具,他做出這個動作時就產(chǎn)生了零界點,如果他只是過來看一看,這個動作不算,因為他沒有對我的就餐產(chǎn)生影響。
臨界區(qū)
任何可能產(chǎn)生臨界點的區(qū)域就是臨界區(qū),鎖需要保護(hù)的是整個臨界區(qū)。因為服務(wù)員是在餐廳來回走動,如果他發(fā)現(xiàn)某位置上已是杯盤狼藉,沒有客人且也沒有任何提示,所以從客人離開桌子和服務(wù)員的視線直到回到座位上之前,他都有可能會來收取餐具,所以我在離開時,放置眼鏡以作提示,直到我再次回到座位上。這段時間就是一個臨界區(qū),我們需要上鎖保護(hù)的是這段時間,而非一點。
總結(jié)
同步機(jī)制是為了保護(hù)數(shù)據(jù)的一致性。
通常所說的“加鎖”其實指的是采用同步機(jī)制,該處的鎖是概念上的。
通常所說的鎖是一個數(shù)據(jù)結(jié)構(gòu)上的實體,也是實現(xiàn)同步機(jī)制的一種手段,但非唯一手段。
因為會臨界點和臨界區(qū)所以才會需要同步機(jī)制,如果多個操作者不會修改數(shù)據(jù),那么就不要同步。
這里的就餐問題和同步機(jī)制在概念上是說得通的,但不能等同鎖的使用。 ?
這里的表格只是僅僅為簡單的說明時序,并沒有表達(dá)原子操作和真正的實現(xiàn)。
[原子操作]:http://www.jianshu.com/p/cb7b726e943c ?
總結(jié)
以上是生活随笔為你收集整理的c语言中锁的作用,C语言实现原子锁(二)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 百度智能云数据众包,更安全、更优质的数据
- 下一篇: FPGA书籍