nlib
nn::nlib::LockFreeBroadcastQueue< T > クラステンプレートfinal

指定された数のリスナーがキューから要素を取得できます。全てのリスナーが取得後、要素はキューから削除されます。 [詳解]

#include "nn/nlib/LockFree.h"

公開型

typedef UniquePtr< const T, empty_func > DequeueType
 Dequeue()の引数となる型です
 

公開メンバ関数

errno_t Enqueue (const T *obj) noexcept
 キューに要素を追加します。スレッドセーフです。 [詳解]
 
errno_t Dequeue (int32_t listener_id, DequeueType &obj) noexcept
 リスナーを指定してキューから要素を読み込みます。異なるlistener_idを利用している場合はスレッドセーフです。 [詳解]
 
size_t GetListenerCount () const noexcept
 Init()で指定したリスナーの数を返します。スレッドセーフです。
 
void SwapUnsafe (LockFreeBroadcastQueue &rhs) noexcept
 オブジェクトをスワップします。スレッドセーフではありません。
 
コンストラクタ、デストラクタ、及び初期化
 LockFreeBroadcastQueue () noexcept
 デフォルトコンストラクタです。
 
 ~LockFreeBroadcastQueue () noexcept
 デストラクタです。 [詳解]
 
errno_t Init (size_t max_size, size_t listeners) noexcept
 キューを初期化します。スレッドセーフではありません。 [詳解]
 

詳解

template<class T>
class nn::nlib::LockFreeBroadcastQueue< T >

指定された数のリスナーがキューから要素を取得できます。全てのリスナーが取得後、要素はキューから削除されます。

テンプレート引数
Tキューの要素の型です。
説明
全てのリスナーが取得を終えるまでは、要素となるオブジェクトは破壊されないので注意してください。 以下がコード例です。
struct MyMessage { const char* text; };
const int kNumReceivers = 3;
errno_t e = queue.Init(128, kNumReceivers);
SUCCEED_IF(e == 0);
std::unique_ptr<MyMessage> obj;
const char* message_list[] = {
"Hello, this is the queue for broadcasting messages",
"The messages are shared among the listeners.",
"They are preserved until all the listeners read them.",
"They are to be deleted automatically.",
nullptr
};
for (auto& message : message_list) {
obj.reset(new (std::nothrow) MyMessage());
SUCCEED_IF(!!obj);
obj->text = message;
queue.Enqueue(obj.release());
}
std::thread th_list[kNumReceivers];
for (int i = 0; i < kNumReceivers; ++i) {
th_list[i] = std::thread([&](int listender_id) {
for (;;) {
while (queue.Dequeue(listender_id, ptr) != 0) { nlib_yield(); }
if (!ptr->text) break;
nlib_printf("thread %d receives '%s'\n", GetMyThreadId(), ptr->text);
}
}, i);
}
for (auto& th : th_list) { th.join(); }
/*
Output:
thread 20568 receives 'Hello, this is the queue for broadcasting messages'
thread 20568 receives 'The messages are shared among the listeners.'
thread 20516 receives 'Hello, this is the queue for broadcasting messages'
thread 20568 receives 'They are preserved until all the listeners read them.'
thread 20516 receives 'The messages are shared among the listeners.'
thread 20568 receives 'They are to be deleted automatically.'
thread 22760 receives 'Hello, this is the queue for broadcasting messages'
thread 20516 receives 'They are preserved until all the listeners read them.'
thread 22760 receives 'The messages are shared among the listeners.'
thread 20516 receives 'They are to be deleted automatically.'
thread 22760 receives 'They are preserved until all the listeners read them.'
thread 22760 receives 'They are to be deleted automatically.'
*/

LockFree.h739 行目に定義があります。

構築子と解体子

◆ ~LockFreeBroadcastQueue()

template<class T>
nn::nlib::LockFreeBroadcastQueue< T >::~LockFreeBroadcastQueue ( )
inlinenoexcept

デストラクタです。

説明
要素が残っている場合は、それぞれの要素をDestructorForLockFreeを利用して削除します。 必要な場合は関数テンプレートを特殊化して必要な処理を実行してください。

LockFree.h746 行目に定義があります。

関数詳解

◆ Dequeue()

template<class T>
nn::nlib::LockFreeBroadcastQueue< T >::Dequeue ( int32_t  listener_id,
DequeueType obj 
)
inlinenoexcept

リスナーを指定してキューから要素を読み込みます。異なるlistener_idを利用している場合はスレッドセーフです。

引数
[in]listener_id0以上かつInit()で指定したリスナーの数未満の整数
[out]obj読み込まれた要素
戻り値
0成功した場合
EAGAIN新たに読み取れる要素がキューにない場合
説明
取得した要素は、次にDequeue()するまで有効です。 全てのリスナーがDequeue()を終えないとキューから要素が削除されないことに注意してください。

LockFree.h761 行目に定義があります。

◆ Enqueue()

template<class T>
nn::nlib::LockFreeBroadcastQueue< T >::Enqueue ( const T *  obj)
inlinenoexcept

キューに要素を追加します。スレッドセーフです。

引数
[in]objキューに追加する要素
戻り値
0成功した場合
EAGAINキューが一杯の場合

LockFree.h757 行目に定義があります。

◆ Init()

template<class T>
nn::nlib::LockFreeBroadcastQueue< T >::Init ( size_t  max_size,
size_t  listeners 
)
inlinenoexcept

キューを初期化します。スレッドセーフではありません。

引数
[in]max_sizeキューに格納できる要素の最大数
[in]listenersリスナーの数
戻り値
0成功した場合
EINVALmax_sizeINT32_MAXを超えている場合
ENOMEMメモリの確保に失敗した場合

LockFree.h753 行目に定義があります。


このクラス詳解は次のファイルから抽出されました: