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);
容量capacity
を持つタイプT
の項目を保持する新しいMPMCQueue
構築します。
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();
キュー内の要素の数を返します。
キューが空で、少なくとも 1 つのリーダーが待機している場合、サイズは負の値になる可能性があります。これは同時キューであるため、すべてのリーダーとライターのスレッドが参加するまで、サイズはベスト エフォート型の推測にすぎません。
bool empty();
キューが空の場合は true を返します。
これは同時キューであるため、すべてのリーダーおよびライターのスレッドが参加するまでは、ベスト エフォートの推測にすぎません。
構築と破棄を除くすべての操作はスレッド セーフです。
エンキュー:
デキュー:
参考文献:
同時実行アルゴリズムのテストは困難です。実装をテストするために 2 つのアプローチを使用しています。
boost::lockfree::queue
などと比較します。 static_assert
の代わりに C++20 の概念を使用します。 std::hardware_destructive_interference_size
を使用します[[nodiscard]]
属性を追加するこのプロジェクトは Erik Rigtorp <[email protected]> によって作成されました。