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 jt([&]{
// 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++: ??