void run();
概要
run_loop
のFIFOキュー上にある作業を逐次実行する。
run_loop
動作説明のため、説明専用のメンバ関数pop-front
, push-back
を導入する。
finish
およびpop-front
, push-back
は不可分(atomically)に実行される。
説明専用メンバ関数 pop-front
run-loop-opstate-base* pop-front();
効果 : 下記条件のいずれか一つがtrue
になるまでブロックする。
count == 0
かつstate
が終了中(finishing)のとき、pop-front
はstate
を終了済み(finished)に設定してnullptr
を返す。count > 0
のとき、count
を1
減算してFIFOキューから先頭要素を削除し、同要素(ポインタ値)を返す。
説明専用メンバ関数 push-back
void push-back(run-loop-opstate-base* item);
効果 : FIFOキューの末尾にitem
を追加してcount
を1
加算する。
同期操作 : この操作は同item
を取得するpop-front
操作に対して同期する。
事前条件
説明専用メンバstate
は開始(starting)もしくは終了中(finishing)であること。
効果
説明専用メンバstate
が開始(starting)の場合、実行中(running)に変更する。
そうでなければ、state
を変更しない。
続いて、以下と等価 :
while (auto* op = pop-front()) {
op->execute();
}
同期操作
run
とデストラクタ以外のメンバ関数同時呼び出しは、データ競合を引き起こさない。
例
#include <print>
#include <thread>
#include <execution>
namespace ex = std::execution;
int main()
{
ex::run_loop loop;
std::println("starting");
std::jthread th([&]{
// 2) 別スレッドからfinishを呼び出し
std::println("finishing");
loop.finish();
});
// 1) メインスレッド上でrunを呼び出すとブロッキングする
loop.run();
// 3) ブロッキング解除されてメインスレッドを再開
std::println("finished");
}
出力
starting
finishing
finished
バージョン
言語
- C++26
処理系
- Clang: ??
- GCC: ??
- ICC: ??
- Visual C++: ??