2013-10-09 81 views
0

我對鎖定有點困惑。具體來說,這裏的代碼從維基百科關於消費者生產者問題。在同一個鎖上多次等待

http://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem#Example_in_C.2B.2B

發生了什麼事,如果有超過1個生產者等待添加到隊列?如果消費者從隊列中消耗了一些工作併發出通知以指示隊列未滿,則他們都嘗試推送隊列中的作業,這需要queue.push方法爲線程安全。由於它們都可以修改隊列,所以這段代碼可能會中斷。我錯過了什麼嗎?

回答

4

是的,你錯過了xmutex被鎖定的事實,所以只有一個生產者可以一次推送任何東西。

當您在condition_variable上等待時,您必須通過一個鎖定的互斥鎖,該鎖定互斥鎖將在等待時解鎖。等待調用返回時,互斥鎖將被重新鎖定。

雖然所有生產者都會收到is_not_full.notify_all();事件的通知,並且都會醒來,但他們只能一次重新獲得一個鎖,即xmutex。這就是互斥體的全部要點。

+0

最重要的是,你通常只有一個生產者。如果已經有很多生產者並行運行,他們也可以接受消費者的工作。生產者/消費者的主要觀點(極少數例外)是在_m_工作線程或執行核心上均勻分配_n_可並行化的任務。如果有人期望有幾個生產者,信號量將會更加安全(避免你提到的雷鳴羣體問題)。 – Damon

+0

這個實現仍然有另一個問題。如果生產者的數量多於max_products(在這個例子中等於10),那麼有可能有10個生產者在等待,當他們都被喚醒時,他們都會加入到隊列中,儘管它是線程安全的,隊列中的產品數量可以超過10個,這是最大允許的數量。 – user40129