2014-01-23 48 views
12

我怎樣才能讓隊列線程安全?我需要推/彈出/前/後並清除。有什麼類似的提升?是std ::隊列線程安全與生產者和多個消費者

我有一個生產者和一個或多個消費者。

+0

調查[mutexes](http://vichargrave.com/multithreaded-work-queue-in-c/)。 – Martol1ni

+1

你的標題問他們是否是線程安全的,但你的開頭句子問你如何使他們如此。所以你已經知道標題問題的答案了。 – WhozCraig

+0

可能的重複:C++ 11線程安全隊列(http://stackoverflow.com/questions/15278343/c11-thread-safe-queue) – yasouser

回答

1

您必須保護對std::queue的訪問。如果您使用提升保護,使用boost::mutex。現在,如果你有多個閱讀器和一個作者線程看boost::shared_lock(讀者)和boost::unique_lock(作家)。

但是如果你會遇到作家線程餓死看看boost::shared_mutex

+2

我懷疑多讀者可以同時安全地讀取隊列。對於這個問題,我相信讀者會將項目從隊列中彈出。彈出操作修改隊列,因此必須在隊列上保留排它鎖。在其他上下文中,「讀者」一詞用於表示不進行修改並僅查看值的代碼。如果在這個問題中讀者正在調用peek而不是pop,那麼他們會滿足這個標準,並且共享鎖會起作用。 – Jason

+0

@Jason,一種可能的解決方案可能是一個帶有原子CAS機制的可變成員標誌,它允許每個讀者線程處理隊列中的一個唯一項目而不彈出,並且定期清理階段(獨佔鎖定)可以幫助清理加工物品。 – Fox

0

你必須保護它,例如與std::mutex,操作。如果你還沒有C++ 11,Boost會成爲一種替代方案。

+2

儘管如此,還是需要一些額外的同步(比如說你想在彈出之前檢查隊列是否爲空,這不是原子性的,即使各個操作同步也可能失敗)。 – juanchopanza

9

std::queue如果一個或多個線程正在寫入,則線程不安全。它的接口不利於線程安全實現,因爲它有單獨的方法,如pop(),size()empty(),這些方法必須在外部進行同步。

一個常見的方法*是實現一個接口更簡單的隊列類型,並在內部使用鎖定機制來提供同步。

*搜索「併發隊列C++」應該會產生很多結果。我實現了一個非常簡單的玩具here,其中的限制是只使用標準的C++。另請參閱Anthony Williams的書C++併發行爲以及他的博客。

+0

感謝您的鏈接!非常好的解釋。 – ikku100

相關問題