Boost.Lockfreeは、スレッドセーフとロックフリーのコンテナを提供します。このライブラリーからのコンテナはアクセスを同期することなく、複数のスレッドからアクセスすることができます。
1.ブースト:: lockfree :: spsc_queue
#include <ブースト/ lockfree / spsc_queue.hpp> の#include <スレッド> の#include <iostreamの> ブースト:: lockfree :: spsc_queue < 整数 > Q(100) 。 int型の合計= 0 ; ボイド農産物() { ため(int型 i = 1 ; iは= < 100 ++; I) q.push(i)を、 } ボイド)(消費 { int型、iは 一方、(q.pop(I)) の和 + = I。 } int型)(主 { はstd ::スレッドT1(生産) STD ::スレッドT2(消費します)。 t1.join(); t2.join(); 消費(); std :: coutの <<合計<< はstd ::てendl; リターン 0 ; }
後押し:: lockfreeを:: spsc_queueは正確に一つのスレッドがキューに書き込み、正確に一つのスレッドがキューから読み取らユースケース用に最適化されています。クラス名に略称SPSCは、1つのプロデューサ/単一消費者の略です。
関数農産物を()を実行する最初のスレッドは、容器100に番号1を加算します。()を消費実行する第二のスレッドは、容器から番号を読み取り、合計でそれらを加算します。コンテナブースト:: lockfree :: spsc_queue explicitylyは二つのスレッドからの同時アクセスをサポートしているので、スレッドを同期する必要はありません。
キューのサイズは、コンストラクタに渡されます。後押し:: lockfreeを:; spsc_queueは循環バッファで実装されています。キューがいっぱいになっているため、値を追加することができない場合は、プッシュ()はfalseを返します。
ブースト:: lockfree ::容量を持つ2ブースト:: lockfree :: spsc_queue
書式#include <ブースト/ lockfree / spsc_queue.hpp> の#include <ブースト/ lockfree / policies.hpp> の#include <スレッド> の#include <iostreamの> 使用して名前空間ブースト:: lockfreeを。 spsc_queue < int型、容量< 100 >> Q; int型の合計= 0 ; ボイド農産物() { ため(int型 i = 1 ; iは= < 100 ++; I) q.push(i)を、 } ボイド消費() { ながら(q.consume_one([](int型のI){合計+ = 私; })) 。 } int型のmain() { STD ::スレッドT1 {生産}。 STD ::スレッドT2 {消費}。 t1.join(); t2.join(); q.consume_all([](int型 i)が{和+ = I;}); std :: coutの <<合計<< はstd ::てendl; リターン 0 ; }
容量は、実行時に設定することはできません。
consume_oneは())(ただのポップのように番号を読み取って、その数は、発信者への参照を通じて返されません。これは、ラムダ関数への唯一のパラメータとして渡されます。スレッドが終了すると、main()
メンバ関数を呼び出してconsume_all()
、代わりにconsume()
。consume_all()
以下のように動作しますconsume_one()
が、キューが呼び出しの後に空であることを確認します。consume_all()
限り、キュー内の要素があるとしてラムダ関数を呼び出します。
3.ブースト:: lockfree ::キュー変数コンテナのサイズを持ちます
#include <ブースト/ lockfree / queue.hpp> の#include <スレッド> の#include <原子> の#include <iostreamの> ブースト:: lockfree ::キュー < 整数 > Q { 100 }。 std ::原子 < 整数 >和{ 0 }。 ボイド農産物() { ため(int型 I = 1 ; I <= 10000 ; ++ I) q.push(I)。 } ボイド)(消費 { int型、iは 一方、(q.pop(I)) の和 + = I。 } INT メイン() { STD ::スレッドT1 {生産}。 STD ::スレッドT2 {消費}。 STD ::スレッドT3 {消費}。 t1.join(); t2.join(); t3.join(); 消費(); std :: coutの <<合計<< はstd ::てendl; リターン 0 ; }
つ以上のスレッドがキューから読み取るため、クラスブースト:: lockfree :: spsc_queueを使用することはできません。
デフォルトでは、ブースト:: lockfree_queueは循環バッファで実装されていません。より多くのアイテムが容量に設定されているよりもキューに追加されている場合、それはatuomatically増加しています。後押し::初期サイズが十分でない場合lockfree ::キューは動的に追加のメモリを割り当てます。
4.ブースト:: lockfree ::キュー一定のコンテナのサイズを持ちます
書式#include <ブースト/ lockfree / queue.hpp> の#include <スレッド> の#include <原子> 書式#include <iostreamの> 使用して名前空間ブースト:: lockfreeを。 キュー < INT、fixed_sized < 真 >> Q { 10000 }。 std ::原子 < 整数 >和{ 0 }。ボイド農産物() { ため(int型 I = 1 ; I <= 10000 ; ++ I) q.push(I)。 } ボイド)(消費 { int型、iは 同時に (q.pop(I)) の和 + = I。 } int型のmain() { STD ::スレッドT1 {生産}。 STD ::スレッドT2 {消費}。 STD ::スレッドT3 {消費}。 t1.join(); t2.join(); t3.join(); 消費(); std :: coutの <<合計<< はstd ::てendl; リターン 0 ; }
ブースト:: lockfree :: fixed_sizedは、テンプレートパラメータとして渡されるため、キューの容量は一定です。容量はリザーブ()を使用していつでも更新することができるコンストラクタにパラメータとして渡されます。
キューは万個の要素の容量を有します。のでconsume()
挿入万の番号キューに、上限を超えていません。それを超えた場合は、push()
戻ってきますfalse
。