在VS2010中引入的併發運行時,有一個concurrent_queue類。它有一個非阻塞try_pop()函數。
與英特爾線程構建模塊(TBB)類似,從版本2.1升級到2.2時,阻止了pop()調用。爲什麼concurrent_queue非阻塞?
我想知道阻塞呼叫有什麼問題。爲什麼從TBB中刪除?爲什麼沒有阻塞concurrent_queue?
我處於需要阻塞併發隊列的情況,而且我不想忙於等待。 除了自己寫一個隊列,在併發運行時還有另外一種可能嗎?
在VS2010中引入的併發運行時,有一個concurrent_queue類。它有一個非阻塞try_pop()函數。
與英特爾線程構建模塊(TBB)類似,從版本2.1升級到2.2時,阻止了pop()調用。爲什麼concurrent_queue非阻塞?
我想知道阻塞呼叫有什麼問題。爲什麼從TBB中刪除?爲什麼沒有阻塞concurrent_queue?
我處於需要阻塞併發隊列的情況,而且我不想忙於等待。 除了自己寫一個隊列,在併發運行時還有另外一種可能嗎?
從a comment from Arch Robison,並沒有得到遠遠超過"horse's mouth"是(一):
PPL的concurrent_queue
沒有阻止彈出,因此同樣沒有tbb::strict_ppl::concurrent_queue
。阻擋彈出窗口可在tbb::concurrent_bounded_queue
中找到。
忽略阻塞彈出的設計參數是,在很多情況下,阻塞的同步是在隊列外部提供的,在這種情況下,在隊列內執行阻塞就成爲不必要的開銷。
另一方面,舊的tbb::concurrent_queue
的阻擋流行音樂在沒有外部同步的用戶中很受歡迎。
所以我們分割功能。不需要阻塞或有界的用例可以使用新的tbb::concurrent_queue
,而需要它的用例可以使用tbb::concurrent_bounded_queue
。
的(a)拱是線程構建模塊的建築師。
如果您需要阻塞流行而沒有繁忙的等待,您需要一種信令方法。這意味着推送器和poper之間的同步,並且隊列不再沒有(昂貴的)同步原語。你基本上會得到一個正常的同步隊列,其中有一個條件變量用於通知推送者,這不在concurrent_ *集合中。
從隊列的角度來看,沒有任何情況需要需要來阻止插入或刪除。您可能需要阻止並等待插入的事實並不重要。
您可以通過使用條件變量或計數信號量或沿着這些行(無論您的特定API提供了什麼)來實現所需的功能。你的麻煩不是阻塞/非阻塞;這聽起來像一個經典的生產者 - 消費者。
問題是,如果併發運行時中有另一個選項提供阻塞隊列功能,因爲concurrent_queue沒有,並且在VS2010中有一個選項。
Arch的評論當然是完全正確的,阻塞隊列和解鎖隊列是不同的用例,這就是VS2010和TBB中不同的原因。
在VS2010中你可以使用位於模板類unbounded_buffer中的適當方法來調用enqueue和dequeue。
-Rick
與封'pop',可以實現* *「經典的生產者 - 消費者」大約兩行代碼使用TBB,而無需編寫任何同步原語自己。 (消費者做'while(true)消費(Q.pop());'和生產者'while(true)Q.push(produce());'。)沒有阻塞的'pop',同樣的問題需要至少兩倍的代碼:即爲每個隊列記錄一個額外的條件變量。 但是,正如paxdiablo所說,'tbb :: concurrent_bounded_queue'繼續提供阻塞'pop'功能,並且基本上是對'concurrent_queue'的一種直接替代。 – Quuxplusone 2012-08-20 23:41:53