最終更新日時: 2026年04月23日 21時23分31秒 (JST)
yoh が更新

履歴 編集

function
<execution>

# std::execution::run_loop::run(C++26)

    void run() noexcept;

## 概要

`run_loop`のFIFOキュー上にある作業を逐次実行する。

`run_loop`動作説明のため、説明専用のメンバ関数`pop-front`, `push-back`を導入する。 `finish`および`pop-front`, `push-back`は不可分(atomically)に実行される。

### 説明専用メンバ関数 `pop-front`

    run-loop-opstate-base* pop-front() noexcept;

効果 : 下記条件のいずれか一つが`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) noexcept;

効果 : 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++: ??

## 関連項目

- `finish`

## 参照

- P2300R10 `std::execution`
- P3396R1 std::execution wording fixes
- LWG4476. `run_loop` should not have a `set_error` completion