執行緒同步: 條件變數
為什麼使用條件變數?
對臨界資源的時序可控性,條件滿足會通知其他等待操作臨界資源的執行緒,類似訊號。 場景:t-day展會排隊參觀/生產者消費者模型
條件變數是什麼?
是一種同步機制,乙個執行緒用於修改這個變數使其滿足其它執行緒繼續往下執行的條件,其它執行緒則接收條件已經發生改變的訊號。
條件變數操作?
初始化和銷毀
pthread_cond_wait
條件不滿足 會釋放鎖並阻塞等待 , 這個函式是原子性操作:1.將執行緒放入條件等待佇列2.釋放鎖
條件滿足 則執行緒會被喚醒並加鎖
pthread_cond_signal 一對一喚醒
喚醒等待佇列中的乙個執行緒
pthread_cond_broadcast 廣播喚醒
喚醒等待佇列中的全部執行緒
為什麼等待和解鎖需要原子操作/為什麼條件變數要使用互斥鎖?
因為pthread_cond_wait中的鎖是為了保護條件變數,防止錯過訊號,如果等待解鎖不是原子性操作,比如執行緒a先解鎖,此時cpu時間片切換到執行緒b,執行緒b加鎖並傳送條件變數訊號,此時再切換到執行緒a,執行緒a還來不及等待就錯過了訊號,就可能會永久阻塞下去。所以,等待和解鎖必須是原子性操作。
為什麼需要while迴圈判斷臨界資源是否存在?
在一對多的情況下,生產者傳送乙個訊號,等待的執行緒被喚醒並加鎖,但是只有乙個執行緒能加鎖,其他執行緒就會阻塞等待鎖,如果這個執行緒用完了臨界資源,其他執行緒不進行判斷就繼續往下走,是不合理的。
singnal要先解鎖還是後解鎖?
如果先解鎖,鎖被沒有阻塞等待的執行緒拿到了,再把臨界資源使用了,解鎖後的singal就沒意義了,也就是虛假喚醒;
先singal喚醒,再讓喚醒的執行緒爭搶鎖,在linux下,有兩個佇列,乙個是cond_wait,乙個是mutex_lock,singal只是讓cond_wait上的執行緒轉移到mutex_lock,不會返回使用者空間,這樣能提高效率。
執行緒互斥: 互斥鎖
為什麼使用互斥鎖?
對臨界資源同時間唯一訪問,保護臨界資源防止修改。 場景:黃牛搶票
互斥鎖是什麼?
是乙個0/1計數器,1代表有資源能操作,0代表沒有資源可以操作。
互斥鎖操作?
初始化和銷毀
加鎖---如果計數為1,置0,進行需要的操作;如果計數為0,則阻塞等待計數變為1
解鎖---計數置為1
執行緒間的同步與互斥
臨界資源 多執行緒共享的資源流就是臨界資源 臨界區 每個執行緒內部,訪問臨界資源的 就叫做臨界區 互斥 任何時刻,互斥保證有且只有乙個執行流進入臨界區,訪問臨界資源,通常對臨界資源起保護作用 原子性 不會被任何排程機制打斷的操作,該操作只有兩態,要麼完成,要麼未完成 多執行緒併發的操作共享變數,會帶...
多執行緒間的同步與互斥
多執行緒與臨界區 多執行緒想要訪問臨界區時,就要對臨界區進行上鎖,這與之前寫到的程序互斥是乙個道理,這也就是防止共享資料被併發訪問的解決方法,這種上鎖叫做互斥鎖 互斥鎖互斥鎖以排他的方式保護共享資料被併發訪問。互斥鎖是乙個二元訊號量 互斥鎖的基本操作 條件變數 條件變數基本原理 互斥鎖能夠解決資源的...
Linux 執行緒同步與互斥
多個執行緒併發的操作共享變數,會帶來 些問題。假設兩個執行緒讀寫相同變數時,執行緒a讀取變數然後給這個變數賦予乙個新的值,但寫操作需要兩個儲存週期。當執行緒b在這兩個寫週期讀取這個變數時,可能會得到不一致的值。為了避免這個問題,就需要互斥,同一時間只允許乙個執行緒訪問該變數。假設乙個場景,現有100...