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

歡迎訪問 生活随笔!

生活随笔

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

linux

记录一次linux信号量sem_t使用bug

發(fā)布時(shí)間:2023/12/31 linux 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 记录一次linux信号量sem_t使用bug 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

linux提供了互斥量pthread_mutex_t(pthread庫) 用于線程間同步,進(jìn)程間同步提供了信號(hào)量sem_t。如果把pthread_mutex_t放到共享內(nèi)存中,并將其屬性設(shè)置為PTHREAD_PROCESS_SHARED,則也能實(shí)現(xiàn)進(jìn)程間的同步,相對(duì)而言比較麻煩。一般直接使用信號(hào)量更加方便。

這里討論使用具名信號(hào)量以便在無血緣關(guān)系的進(jìn)程之間做同步,主要涉及下面5個(gè)函數(shù):

sem_open();//打開或者創(chuàng)建信號(hào)量 sem_wait();//獲取信號(hào)量 sem_post();//掛出信號(hào)量 sem_close();//關(guān)閉信號(hào)量 sem_unlink();//銷毀信號(hào)量

其中sem_unlink()的行為比較讓人迷惑,linux內(nèi)核文檔描述為:

DESCRIPTIONsem_unlink() removes the named semaphore referred to by name. The semaphore name is removed immediately. Thesemaphore is destroyed once all other processes that have the semaphore open close it.

意思是執(zhí)行該函數(shù),會(huì)立即移除信號(hào)量的id名,并嘗試銷毀對(duì)應(yīng)的信號(hào)量實(shí)體,只有所有打開了該信號(hào)量的進(jìn)程都執(zhí)行了sem_close(),執(zhí)行sem_unlink()時(shí)才會(huì)真正銷毀這個(gè)信號(hào)量。問題就出現(xiàn)了,id名與信號(hào)量實(shí)體可能出現(xiàn)分離,因?yàn)楫?dāng)某個(gè)進(jìn)程A關(guān)閉了信號(hào)量(也就是執(zhí)行了sem_close)并嘗試執(zhí)行sem_unlink的時(shí)候,并不能確保其他進(jìn)程關(guān)閉了信號(hào)量,結(jié)果是信號(hào)量實(shí)體無法被真正銷毀,它依然在內(nèi)核中存在,且其他使用該信號(hào)量實(shí)體的進(jìn)程依然可以工作正常。問題是,當(dāng)進(jìn)程A再次打開這個(gè)信號(hào)量時(shí)(使用sem_open(),id名不變),已經(jīng)無法通過id名找到之前那個(gè)信號(hào)量實(shí)體了,打開的是一個(gè)全新的信號(hào)量,雖然id名與之前一樣,內(nèi)容卻已經(jīng)沒有關(guān)聯(lián)了。

??????? 這樣一來,進(jìn)程A就無法與其他進(jìn)程同步了。只有其他進(jìn)程也執(zhí)行一次sem_close,并重新打開這個(gè)id名(sem_open()),才能重新連接到進(jìn)程A打開的那個(gè)信號(hào)量實(shí)體,繼續(xù)同步。因此“The semaphore name is removed immediately”,應(yīng)該理解為"立即解除name 與信號(hào)量實(shí)體的綁定關(guān)系",且解除之后無法重新綁定。

??????? 在使用共享內(nèi)存的過程中,shmctl(id,IPC_RMID,NULL)移除共享內(nèi)存,好像也有類似的問題,沒有實(shí)測(cè)過。

總結(jié):

????????通常當(dāng)一個(gè)進(jìn)程退出時(shí),需要關(guān)閉已經(jīng)打開的信號(hào)量(sem_close),如果信號(hào)量屬于這個(gè)進(jìn)程(在這個(gè)進(jìn)程里面create),還應(yīng)該執(zhí)行sem_unlink;如果信號(hào)量的歸屬權(quán)不是該進(jìn)程,則只應(yīng)該執(zhí)行關(guān)閉。

??????? 現(xiàn)實(shí)使用的時(shí)候,進(jìn)程可能異常掛掉退出,沒有執(zhí)行到sem_close這一步,甚至還沒有來得及掛出信號(hào)量(sem_post)程序就掛了,問題比較復(fù)雜,不僅可能存在數(shù)據(jù)安全,還很有可能造成死鎖。所以最好是當(dāng)某個(gè)進(jìn)程重啟了,其他相關(guān)進(jìn)程也重啟一下,確保所有進(jìn)程打開的是同一個(gè)信號(hào)量實(shí)體,可以一定程度避免信號(hào)量和共享內(nèi)存連接異常的問題。

??????? 當(dāng)然,最好是不要讓程序有異常掛掉的情況,應(yīng)該做好異常捕獲和處理,減少程序未定義行為。

總結(jié)

以上是生活随笔為你收集整理的记录一次linux信号量sem_t使用bug的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

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