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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

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

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

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

這里討論使用具名信號量以便在無血緣關系的進程之間做同步,主要涉及下面5個函數:

sem_open();//打開或者創建信號量 sem_wait();//獲取信號量 sem_post();//掛出信號量 sem_close();//關閉信號量 sem_unlink();//銷毀信號量

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

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.

意思是執行該函數,會立即移除信號量的id名,并嘗試銷毀對應的信號量實體,只有所有打開了該信號量的進程都執行了sem_close(),執行sem_unlink()時才會真正銷毀這個信號量。問題就出現了,id名與信號量實體可能出現分離,因為當某個進程A關閉了信號量(也就是執行了sem_close)并嘗試執行sem_unlink的時候,并不能確保其他進程關閉了信號量,結果是信號量實體無法被真正銷毀,它依然在內核中存在,且其他使用該信號量實體的進程依然可以工作正常。問題是,當進程A再次打開這個信號量時(使用sem_open(),id名不變),已經無法通過id名找到之前那個信號量實體了,打開的是一個全新的信號量,雖然id名與之前一樣,內容卻已經沒有關聯了。

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

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

總結:

????????通常當一個進程退出時,需要關閉已經打開的信號量(sem_close),如果信號量屬于這個進程(在這個進程里面create),還應該執行sem_unlink;如果信號量的歸屬權不是該進程,則只應該執行關閉。

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

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

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。