日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux 信号量锁 内核,Linux内核中锁机制之信号量、读写信号量

發(fā)布時間:2024/8/5 linux 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux 信号量锁 内核,Linux内核中锁机制之信号量、读写信号量 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

在上一篇博文中筆者分析了關(guān)于內(nèi)存屏障、讀寫自旋鎖以及順序鎖的相關(guān)內(nèi)容,本篇博文將著重討論有關(guān)信號量、讀寫信號量的內(nèi)容。

六、信號量

關(guān)于信號量的內(nèi)容,實際上它是與自旋鎖類似的概念,只有得到信號量的進程才能執(zhí)行臨界區(qū)的代碼;不同的是獲取不到信號量時,進程不會原地打轉(zhuǎn)而是進入休眠等待狀態(tài)。它的定義是include\linux\semaphore.h文件中,結(jié)構(gòu)體如圖6.1所示。其中的count變量是計數(shù)作用,通過使用lock變量實現(xiàn)對count變量的保護,而wait_list則是對申請信號量的進程維護的等待隊列。

圖6.1??????信號量的結(jié)構(gòu)體定義

我們首先看下它是如何使用的,首先定義一個信號量,然后初始化信號量,它包括兩種方法。如圖6.2所示。方法1:簡單的初始化,定義信號量的個數(shù)由val決定,實際上val值即是賦給信號量結(jié)構(gòu)體中的count變量;方法2是直接將結(jié)構(gòu)體中count值設(shè)置成1,此時信號量可用于實現(xiàn)進程間的互斥量。注意:對于信號量的初始化函數(shù)Linux最新版本存在變化,本文所采用的Linux版本已不存在如init_MUTEX和init_MUTEX_LOCKED等初始化函數(shù),同時也更換了名字等,這點讀者在閱讀的時候需要下,因此筆者建議以后在編程中遇到需要使用信號量的時候盡量采用sema_init(struct semaphore *sem, int val)函數(shù),因為這個函數(shù)就目前為止從未發(fā)生變化。

圖6.2??????信號量的初始函數(shù)

下面我們討論如何獲得信號量,它主要包括三個函數(shù),第一個函數(shù)表示當(dāng)信號申請不到時會進程會休眠;對于第二個函數(shù)來說,它表示如果當(dāng)進程因申請不到信號量而進入睡眠后,能被信號打斷,這里所說的信號是指進程間通信的信號,比如我們的Ctrl+C,但這時候這個函數(shù)的返回值不為0;第三個函數(shù)表示信號量無論是否獲得,都將立即返回,但返回值會根據(jù)是否申請成功而定,同時這個函數(shù)也不會導(dǎo)致睡眠。最后的up函數(shù),這個還是很好理解的,就是釋放信號量,進而喚醒隊列中的等待信號量的進程。函數(shù)如圖6.3所展示一般。

圖6.3??????信號量的獲得和釋放函數(shù)

接下來筆者將舉幾個例子,依次如圖6.4,圖6.5所示。圖6.4的例子仍是實現(xiàn)一個設(shè)備只能被一個進程打開。例子很簡單,這里便不再細說,主要體現(xiàn)到底如何使用信號量。如圖6.4所展示。

圖6.4??????信號量的使用示例

如圖6.5實現(xiàn)的是進程間的同步問題。實際上,當(dāng)把信號量的初始值為0,則可以實現(xiàn)同步了。正如圖6.5所展示一般,對于執(zhí)行單元A而言,如果執(zhí)行單元B不執(zhí)行up函數(shù),執(zhí)行單元A就因為申請不到進程而睡眠,直至up函數(shù)被調(diào)用,所以執(zhí)行代碼b前必須等到執(zhí)行單元B執(zhí)行完代碼c。相信這個內(nèi)容在操作系統(tǒng)課程都均有提及。

圖6.5??????信號量實現(xiàn)同步示例

討論過示例后,相信讀者對于信號量的使用有了比較好的了解。下面讓我們來簡單的討論下它的實現(xiàn)機制。通過了解信號量的結(jié)構(gòu)體,可以發(fā)現(xiàn)結(jié)構(gòu)體中除了使用自旋鎖機制外,就是count值的變化(這一點先前已提及)。它的源碼如圖6.6,圖6.7所示。

圖6.6??信號量down函數(shù)內(nèi)核源碼圖6.7??信號量up函數(shù)內(nèi)核源碼

從源碼中可以看到信號量利用自旋鎖的相關(guān)函數(shù)實現(xiàn)了對count變量的保護,通過判斷變量是否大于0以及自增減來實現(xiàn)信號量的申請和釋放。也是因為這一點,所以信號量能夠?qū)崿F(xiàn)同步機制。

另外,關(guān)于源碼中的__down和__up函數(shù)的實現(xiàn)內(nèi)容,它們其實是維護申請信號量的進程的鏈表隊列(增加、刪除操作),以及進程調(diào)度方面的一些信息(超時機制),從而讓進程實現(xiàn)休眠。由于其中的源碼量較為龐大,涉及的內(nèi)容也較多,故這里不再深入討論,感興趣的可以查閱相關(guān)資料。

關(guān)于信號量的內(nèi)容還有一點需要提及,我們知道信號量時進程級的,因此對于它的使用必然是當(dāng)占用資源較長時間的時候。這點在使用信號量的使用需要重點考慮,反之,則容易影響程序的性能等。OK,至此,關(guān)于信號量的內(nèi)容即討論到此。

七、讀寫信號量

接下來筆者將討論有關(guān)讀寫信號量的內(nèi)容,這部分是較難的一部分,需分析較多的源碼。同樣,我們首先看下它主要能夠做些什么:讀寫信號量與信號量的關(guān)系如同自旋鎖與讀寫自旋鎖的關(guān)系,它允許N個讀操作同時訪問共享資源,但最多只能有一個寫操作。它的定義位置是在arch\x86\include\asm\rwsem.h以及kernel\rwsem.c中。關(guān)于它的結(jié)構(gòu)體的定義,如圖7.1所示。顯然,它的結(jié)構(gòu)體定義和信號量的結(jié)構(gòu)體定義如出一轍。

圖7.1??????讀寫信號量的結(jié)構(gòu)體實現(xiàn)

而后了解下它的具體使用方法,如圖7.2所展示的函數(shù)。同其它鎖機制類似,它所提供的接口函數(shù)也是較為簡單,包括這些函數(shù)能實現(xiàn)的功能都差不了多少。

圖7.2??????讀寫信號量的接口函數(shù)

在了解讀寫信號量的定義和使用后,接下來讀者將討論的具體源碼實現(xiàn)。它的具體實現(xiàn)是采用匯編實現(xiàn),比較繞,需配合源碼來一一說明,源碼次序依次如圖7.3至圖7.8所示。為便于分析,下面源碼只給出最為關(guān)鍵的內(nèi)容。

對于圖7.3所展示的內(nèi)容主要是讀寫信號量中需要使用的一些宏定義,具體為何取這個值筆者就不大了解了,后續(xù)研究深入了可能會有所體會。

圖7.3??????讀寫自旋鎖的內(nèi)核源碼

圖7.4??????讀寫自旋鎖的內(nèi)核源碼

圖7.5??????讀寫自旋鎖的內(nèi)核源碼

圖7.4和同7.5所示源碼主要體現(xiàn)了讀鎖和寫鎖的實現(xiàn)內(nèi)容。實際上還是利用test指令檢測count變量的值來實現(xiàn)。申請成功的內(nèi)容好理解,其中的xadd指令表示將原操作數(shù)和目的操作數(shù)值相交換,而后相加保存入目的操作數(shù)。一旦讀寫信號量申請失敗,則需要跳轉(zhuǎn)到如圖7.6,圖7.7所示的源碼中。其中圖7.6,圖7.7中所示的源碼沒多少內(nèi)容,最后還是跳轉(zhuǎn)到rwsem_down_read_failed和rwsem_down_write_failed函數(shù)中,通過匯編源碼保存改變相應(yīng)存儲變量的寄存器,從而再次返回到C代碼中,如圖7.8所示的源碼中。由于筆者能力有限,對于圖7.8所示的源碼內(nèi)容中調(diào)用的rwsem_down_write_failed函數(shù)被沒有研究透,故這里并未進一步深入研究。

至此,關(guān)于讀寫信號量的內(nèi)容討論基本結(jié)束,確實由于筆者能力有限,關(guān)于讀寫信號量的內(nèi)容以及本博文的系列內(nèi)容,讀者可進一步深入研究,并歡迎討論。共同進步。

圖7.6??讀寫自旋鎖的內(nèi)核源碼圖7.7??讀寫自旋鎖的內(nèi)核源碼

圖7.8??????讀寫自旋鎖的內(nèi)核源碼

出于文章篇幅的限制,本篇博文到此結(jié)束,后續(xù)將會給出《大話Linux內(nèi)核中鎖機制之完成量、互斥量》,感興趣的讀者可繼續(xù)閱讀后一篇博文。由于筆者水平所限,博文中難免有出錯之處,歡迎讀者指出,大家相互討論,共同進步。

來源:oschina

鏈接:https://my.oschina.net/u/4280386/blog/4238578

與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖

總結(jié)

以上是生活随笔為你收集整理的linux 信号量锁 内核,Linux内核中锁机制之信号量、读写信号量的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。