用 C++11 編寫的有界多生產者多消費者並發隊列。
它經過實戰考驗並每天在生產中使用:
它被以下論文引用:
MPMCQueue< int > q ( 10 );
auto t1 = std::thread([&] {
int v;
q. pop (v);
std::cout << " t1 " << v << " n " ;
});
auto t2 = std::thread([&] {
int v;
q. pop (v);
std::cout << " t2 " << v << " n " ;
});
q.push( 1 );
q.push( 2 );
t1.join();
t2.join();
MPMCQueue<T>(size_t capacity);
建構一個新的MPMCQueue
保存類型為T
容量為capacity
專案。
void emplace(Args &&... args);
使用就地構造對項目進行排隊。如果隊列已滿則阻塞。
bool try_emplace(Args &&... args);
嘗試使用就地構造對項目進行排隊。成功則傳回true
,如果佇列已滿則傳回false
。
void push(const T &v);
使用複製構造對項目進行排隊。如果隊列已滿則阻塞。
template <typename P> void push(P &&v);
使用移動構造對項目進行排隊。僅當std::is_nothrow_constructible<T, P&&>::value == true
時才參與重載決策。如果隊列已滿則阻塞。
bool try_push(const T &v);
嘗試使用複製構造將項目排隊。成功則傳回true
,如果佇列已滿則傳回false
。
template <typename P> bool try_push(P &&v);
嘗試使用移動構造將項目排隊。僅當std::is_nothrow_constructible<T, P&&>::value == true
時才參與重載決策。成功則傳回true
,如果佇列已滿則傳回false
。
void pop(T &v);
透過將項目複製或移動到v
來使項目出隊。如果佇列為空則阻塞。
bool try_pop(T &v);
嘗試透過將項目複製或移動到v
來使項目出隊。成功則傳回true
,如果佇列為空則傳回false
。
ssize_t size();
傳回佇列中的元素數量。
當隊列為空並且至少有一個讀者在等待時,大小可以是負數。由於這是一個並發隊列,因此在所有讀取器和寫入器線程都加入之前,大小只是盡力猜測。
bool empty();
如果隊列為空則傳回 true。
由於這是一個並發隊列,因此在所有讀取器和寫入器線程都已加入之前,這只是盡力猜測。
除了構造和銷毀之外的所有操作都是線程安全的。
入隊:
出隊:
參考:
測試並發演算法很困難。我使用兩種方法來測試實作:
boost::lockfree::queue
等進行比較static_assert
std::hardware_destructive_interference_size
[[nodiscard]]
屬性此專案由 Erik Rigtorp <[email protected]> 創建。