記linux下對條件量的學習(一)

2021-09-12 04:13:15 字數 1529 閱讀 9128

訊號量,互斥量,條件量是執行緒間保證執行緒同步的三種方式,其中訊號量和互斥量是通過堵塞的方式來實現資源的競爭,試想一下,如果有多個消費者執行緒同時在等待乙個生產者生產產品時,如果只用到互斥量,那麼每個消費者執行緒在訪問產品這個臨界資源的時候都需要對互斥量metex進行先上鎖,讀取並且判斷有無產品,再解鎖地操作。但這是在浪費時間和資源,而且這種繁忙查詢的效率非常低。同樣,在每次檢查之間讓執行緒短暫地進入睡眠,比如睡眠1s,但是因此執行緒**就無法最快作出響應。

這樣也就有了條件量的使用,簡單來說,使用條件量可以使原本堵塞的執行緒進入休眠狀態,直到條件滿足,休眠的執行緒被signal喚醒,執行操作,這樣就不會產生競爭

條件量通常是配合互斥量一起用,其中條件量起到了喚醒執行緒的作用,而互斥量起到了保護條件的作用,執行緒在改變條件狀態時首先先鎖住互斥量,改變條件後,傳送訊號,再釋放互斥量。(如果不使用互斥量,當有多個執行緒同時呼叫wait時,「等待執行緒「佇列被多個同時訪問,就會導致資料錯亂)

作用:條件量的初始化

返回值:成功返回,失敗返回-1;

形參:restrict cond :被初始化的條件量

restrict attr: 初始化的屬性,一般設定為空

作用:條件量的銷毀

返回值:成功返回,失敗返回-1;

形參:restrict cond :被銷毀的條件量

作用:執行緒通過呼叫wait進入等待被喚醒的執行緒佇列中

返回值:成功返回,失敗返回-1;

形參:restrict cond :等待的條件量

restrict mutex : 與該條件量配套使用的互斥量

1.釋放mutex鎖

2.使執行緒休眠

3.等待條件改變

需要注意的是,等到條件改變後,爭取到的執行緒應該先對mutex上鎖,再對臨界資源進行操作;為了防止執行緒被誤喚醒,可以用乙個while迴圈巢狀wait,while迴圈的結束條件是對 wait所等待的臨界資源中某個值進行判斷,以此來防止誤喚醒。例如,要等待的資源是某個產品, 最開始產品數 count == 0,執行緒a被喚醒後,從wait中return出來,被while(!count)判斷,判斷此時的產品數量是否等於0,不滿足則說明這是一次有效的wait,執行緒就可以執行接下去的**。否則,說明是一次誤喚醒,執行緒重新進入wait內部。

作用:與wait類似,多了個時間結構體,當等待時間超過預定時間後,執行緒會被喚醒,重新獲取互斥量,然後返回等待超時錯誤。

返回值:成功返回,失敗返回-1;

作用:執行緒通過呼叫signal喚醒 等待被喚醒的執行緒佇列 中的某乙個執行緒

返回值:成功返回,失敗返回-1;

形參:restrict cond :被通知的條件量

作用:執行緒通過呼叫broadcast喚醒 等待被喚醒的執行緒佇列 中的所有執行緒

返回值:成功返回,失敗返回-1;

形參:restrict cond :被通知的條件量

** 需要注意的是 **,執行緒在呼叫signal或者是broadcast的時候,同樣也需要對mutex進行上鎖,再改變臨界資源並且傳送訊號通知,最後解鎖mutex的操作,以保護執行緒佇列和臨界資源。

記linux下對執行緒池的學習及使用(一)

執行緒池就是乙個擁有許多執行緒的乙個容器,通常執行緒池中的執行緒可通過條件量設定為休眠狀態,待到條件改變即執行緒池發現了新的可執行任務的時候,會隨機喚醒乙個等待執行緒從任務佇列中提取任務並且執行。如果沒有執行緒池,可以假想在乙個服務端在要處理的事件的時候,大概可分為三步,分別是 1.建立執行緒 2....

Linux學習之 使條件變數互斥量避免無限等待

view code include include include clthread.h include clexecutivefunctionprovider.h include clmutex.h include clcriticalsection.h include clconditionva...

Linux下的訊號量

linux下的訊號量本身就是臨界資源,所以pv操作都是原子操作。下面是實現二元訊號量的 二元訊號量就是互斥鎖。訊號量 中的semop函式是進行pv操作的核心函式,semop的函式原型為 int semop int semid,struct sembuf sops,unsigned nsops 第乙個...