一年多過去啦,一段時間沒有posix多執行緒的東西,又忘記的差不多略,我打記性咋這麼差,絲毫記不起來怎麼用啦,還是不如爛筆頭啊。
lock->wait->unlock.
在呼叫pthread_cond_wait(cond,mutex)時的執行順序是這樣的:
1. 首先獲取外面的mutex, 然後當前wait push 到乙個等待的queue裡面,然後釋放鎖。但是你看wait的後面又是unlock釋放mutex,這不重複啦嗎?
並不是這樣,請繼續往下看.
2. pthread_cond_signal 首先獲取mutex, 然後通過條件變數傳送訊息,立刻釋放mutex。
3. wait獲取signal的訊息,重新再獲取mutex, 然後執行
在研究pthread_cond_wait的時候總是會聽到一局,wait結束後會重新獲取鎖,這句話很忽悠人,弄來好久才繞過來。
pthread_cond_wait(cond, mutex), 可以展開來理解:
pthread_mutex_unlock(mtx); 當然unlock之前把當前waitpush到queue裡面pthread_cond_wait(cond);
pthread_mutex_lock(mtx);
從知乎上搜尋也發現,有大神說:正是因為程式設計師發現unlock, wait, lock這三個操作始終得在一起,於是才提供略這個api來完成這三個動作。
乙個完整的順序是這樣的:
a:pthread_mutex_lock(mtx); --a1
pthread_cond_wait(cond, mtx); 這一步需要展開:
pthread_mutex_unlock(mtx); --a2
pthread_cond_wait(cond); --a3
pthread_mutex_lock(mtx); --a4
pthread_mutex_unlock(mtx); -- a5
b:pthread_mutex_lock(mtx); --b1
pthread_cond_signal(cond); --b2
pthread_mutex_unlock(mtx); -- b3
如果a先執行,順序是:
a1->a2->a3->b1->b2->a4->a5
如果b先執行,順序是:
b1->b2-b3->a1->a2->a3, 不會進入a4,而是等待新的signal過來,之前一次的已經扔掉拉
為什麼需要加mutex???
in thread1:pthread_mutex_lock(&m_mutex);
pthread_cond_wait(&m_cond,&m_mutex);
pthread_mutex_unlock(&m_mutex);
in thread2:
pthread_mutex_lock(&m_mutex);
pthread_cond_signal(&m_cond);
pthread_mutex_unlock(&m_mutex);
假如1執行緒在呼叫cond_wait時,還沒有進入wait_cond的狀態, 然後執行緒2立馬就呼叫啦cond_signal, 也就是signal比wait要快,這個時候cond_signal就丟失拉,使用啦mutex,則必須等到cond_wait的mutex釋放後,然後執行緒2獲取mutex, 然後才能呼叫cond_signal.
cond_signal為什麼要放在mutex中間呢,放在unlock後面會怎麼樣呢?
pthread_mutex_lock(&m_mutex);******x...
pthread_mutex_unlock(&m_mutex);
pthread_cond_signal(&m_cond);
假如signal之前釋放鎖,這個時候有個低優先順序的任務正在等待mutex, 而這個signal訊息本是為啦去trigger乙個更高優先順序的執行緒的,這樣就會出現低優先順序搶占高優先順序任務的現象,如果放在中間,則會先保證成功trigger本次需要trigger的任務後,然後釋放鎖,然後是其任務獲取這個鎖。
放在中間有沒有問題呢?其實也有:
pthread_mutex_lock(&m_mutex);pthread_cond_signal(&m_cond);
pthread_mutex_unlock(&m_mutex);
在某些執行緒的實現中,會造成等待執行緒從核心中喚醒(收到cond_signal)後又回到核心空間(出發cond_wait執行緒後然後又會獲取mutex),會有效能問題。
C 條件變數使用詳解
目錄 condition variable介紹 細節說明 wait wait for說明 wait 成員函式 wait for 成員函式 notify all notify one 虛假喚醒 條件變數使用 在c 11中,我們可以使用條件變數 condition variable 實現多個執行緒間的同...
Linux下條件變數詳解
條件變數可以讓執行緒在滿足特定的條件下暫停 睡眠 需要與互斥量配合使用。pthread cond t cond pthread cond initializer 通過巨集對條件變數初始化 int pthread cond init pthread cond t cond,pthread condat...
互斥鎖與條件變數詳解
互斥量 mutex 從本質上說是一把鎖,在訪問共享資源前對互斥量進行加鎖,在訪問完成後釋放互斥量上的鎖。在互斥量進行加鎖以後,任何其它試圖再次對互斥量加鎖的執行緒將會阻塞直到當前執行緒釋放該互斥鎖。如果釋放互斥鎖時有多個執行緒阻塞,所有在該互斥鎖上的阻塞執行緒都會變成可執行狀態,第乙個變為可執行狀態...