天天看點

用條件變量來解決生産者消費者問題

在上一篇文章中,我使用了匿名信号量

什麼是條件變量?

我們可以設想一個場景:線程A需要某個條件成立才能繼續執行,否則一直等待下去,而線程B執行過程中使線程的執行條件成立,并且喚醒A。

舉個例子,在生産者消費者模型中,消費者如果看到緩沖區為空時,就等待,而生産者往緩沖區添加完資料後,喚醒消費者。

其中這個場景中,可以POSIX的條件變量來實作。

以下是條件變量所需要的函數

這裡大家就百度怎麼用,或者在Linux中用man 3 pthread_cond_***的方法也行。

其中重點講一下的是 pthread_cond_wait這個函數。

條件變量是要和互斥量配合使用的,而pthread_cond_wait的搭配互斥量後是執行者三步操作。

第一,條件不成立時,釋放互斥量(将互斥量解鎖)。

第二,阻塞自己,讓别的線程開始執行。

第三,當被其他的線程喚醒時,重新獲得互斥量(重新将互斥量加鎖),并執行後續代碼。

掌握了這個之後,就來說下條件變量的使用規範。

第一,等待條件代碼

第二,修改條件代碼

在這裡的一個難點是,第一段條件等待代碼為什麼不用if而用while呢?在man 3 pthread_cond_wait 之後發現這樣一段話

If a signal is delivered to a thread waiting for a condition variable, upon return from the signal handler the thread resumes waiting for the condition variable as if it was not interrupted, or it shall return zero due to spurious wakeup.

也就是說,喚醒條件的信号,可以喚醒多個線程,但是隻能允許一個信号通路,也就是說,是以等待線程需要不斷的用while輪詢一直到達到條件了才行。

好了,講了這麼多我們用它來做個生産者消費者執行個體吧。

最後,下圖為代碼執行結果。

用條件變量來解決生産者消費者問題

繼續閱讀