[英]How does pthread_cond_wait (conditon variable) unblock all threads only once, not multiple times?
我已經成功實現了生產者線程和2個工作線程或消費者線程。
生產者線程使用pthread_cond_broadcast廣播條件。 並且工作線程被pthread_cond_wait阻止。
該代碼看起來像這樣:
線程1(生產者線程):
pthread_mutex_lock
pthread_cond_broadcast
pthread_mutex_unlock
線程2(工人/消費者線程):
work = 1
while(1)
{
pthread_mutex_lock
while(!work)
{
work = 1;
pthread_cond_wait
}
// Thread operation
work = 0;
pthread_mutex_unlock
}
線程3(工人/消費者線程):
work = 1
while(1)
{
pthread_mutex_lock
while(!work)
{
work = 1;
pthread_cond_wait
}
// Thread operation
work = 0;
pthread_mutex_unlock
}
我的問題是,為什么線程2或線程3不會重新執行自身?
換句話說,當條件由線程1廣播時,可以說線程2首先對該條件解除阻塞,執行線程操作並調用thread_cond_wait並阻塞自身。
現在,線程3在該條件下解除阻塞,執行線程操作並調用thread_cond_wait並阻塞自身。
在這個時間點,兩個線程都被阻塞以等待條件,條件變量是否被重置? 如果是這樣,它怎么知道何時重置,因為我可以有5個工作線程來代替2個工作線程?
為什么在相同條件下線程2和線程3不會再次解除自身阻塞?
我想了解內部機制,即線程如何針對特定條件解除阻塞一次,而不是再次阻塞,直到發送新廣播為止。
我已經嘗試閱讀有關此內容的信息,但我所能看到的是,如果發送了條件廣播,則所有等待該條件的線程都將被阻塞。 我不明白的是為什么同一個線程在相同條件下不會多次解除阻塞?
我嘗試查看pthread_cond_t,但沒有任何線索。
對於我所缺少或錯誤思考的任何幫助或建議,將不勝感激。
謝謝
我的問題是,為什么線程2或線程3不會重新執行自身?
因為那不是條件變量的工作方式。
換句話說,當條件由線程1廣播時,可以說線程2首先對該條件解除阻塞,執行線程操作並調用thread_cond_wait並阻塞自身。
現在,線程3在該條件下解除阻塞,執行線程操作並調用thread_cond_wait並阻塞自身。
在這個時間點,兩個線程都被阻塞以等待條件,條件變量是否被重置?
這個問題表明條件變量所代表的狀態模型很差,因為答案是肯定和否定。 實現細節可能相差很大,但是從概念上講,由CV管理的主要狀態由當前在CV上等待的線程的“等待集”組成。 這些線程無法繼續執行, 即它們在CV上被阻塞。
簡歷上可以執行三個主要操作:
CV不攜帶指示它們是否已被信號通知的持久狀態。 他們只知道他們的等待集和(在pthreads實現中)一個互斥體,從等待集中刪除的線程必須先獲取一個互斥體,然后它們才能從等待操作返回。 無需重置CV就可以使其接受更多線程進入其等待集中。
如果是這樣,它怎么知道何時重置,因為我可以有5個工作線程來代替2個工作線程?
它不會重置,在任何意義上都不會與已描述的操作有所不同。 等待它的任何線程都將添加到等待集中,並且只要它保留在那里就沒有資格進行調度。 從根本上說,CV上的任何信號和廣播操作都會影響該操作的等待時間。 從等待集中刪除的線程不再在CV上被阻止,而是在獲取關聯的互斥體時可能被阻止。
為什么在相同條件下線程2和線程3不會再次解除自身阻塞?
因為那不是條件變量的工作方式。
線程2和3再次等待是CV支持的唯一一種重置。 這些線程已被讀取到等待集中,沒有理由認為它們將在對該CV執行(另一個)信號或廣播操作之前繼續執行。 沒有過去的信號/廣播的存儲,只有等待集的當前內容。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.