最終更新日時(UTC):
が更新

履歴 編集

class
<execution>

std::execution::inline_scheduler(C++26)

namespace std::execution {
  class inline_scheduler {
    class inline-sender; // exposition only
    template <receiver R>
    class inline-state;  // exposition only

  public:
    using scheduler_concept = scheduler_tag;

    constexpr inline-sender schedule() noexcept { return {}; }
    constexpr bool operator==(const inline_scheduler&) const noexcept = default;
  };
}

概要

inline_schedulerは、インラインでタスクを実行するSchedulerである。

schedule操作により得られるSenderReceiver接続(connect)したOperationStateは、開始(start)したスレッド上で即座に値完了する。

戻り値task<T, E>を持つタスクコルーチンのScheduler型として利用すると、コルーチン内でco_awaitから再開(resume)時のスケジューリング操作を回避できる(動作詳細はawait_transformを参照)。

クラス仕様

inline_scheduler型の全オブジェクトは等しい。inline_scheduler型の部分式schクエリオブジェクトq、部分式のパックargsとしたとき、式sch.query(q, args...)inline-attrs<set_value_t>.query(q, args...)と等価な式となる。

説明専用のクラスinline-sendersenderを満たす型とする。completion_signatures_of_t<inline-sender>は、completion_signatures<set_value_t()>となる。

説明用のsndrinline-sender型の式とする。CScompletion_signatures<set_value_t()>としたとき、rcvrreceiver-of<decltype((rcvr)), CS>trueとなる式とする。式connect(sndr, rcvr)の型はinline-state<remove_cvref_t<decltype((rcvr))>>であり、式((void)sndr, auto(rcvr))が潜在的に例外送出(potentially-throwing)するときに限って潜在的に例外送出する。

説明用のoinline-state<Rcvr>型の非const左辺値とし、REC(o)oを返す接続(connect)呼び出しへ渡した式rcvrで初期化されたRcvr型の非const左辺値参照とする。

  • REC(o)が参照するオブジェクトは、oが参照するオブジェクトの生存期間(lifetime)で有効である。
  • start(o)は、set_value(std::move(REC(o)))と等価。

説明専用クラステンプレートinline-attrs

template<class Tag>
struct inline-attrs {
  see below
};
部分式envとしたとき、inline-attrs<Tag>{}.query(get_completion_scheduler<Tag>, env)get_scheduler(env)と等価な式となる。

部分式envとしたとき、inline-attrs<Tag>{}.query(get_completion_domain<Tag>, env)get_domain(env)と等価な式となる。

メンバ関数

名前 説明 対応バージョン
(constructor) コンストラクタ C++26
(destructor) デストラクタ C++26
schedule スケジュールSenderを返す C++26

メンバ型

名前 説明 対応バージョン
scheduler_concept scheduler_tag C++26

#include <execution>
#include <thread>
#include <print>
namespace ex = std::execution;

// ex::task用のカスタム環境
struct TaskEnv {
  using start_scheduler_type = ex::inline_scheduler;
};

ex::task<void> f(ex::scheduler auto sch)
{
  std::println("step1 main#{}", std::this_thread::get_id());

  // スケジューラを変更してサブタスクを実行
  co_await (ex::schedule(sch) | ex::then([]{
    std::println("step2 worker#{}", std::this_thread::get_id());
  }));

  // デフォルト(task_scheduler)タスクコルーチンのco_await式では、
  // Scheduler Affinity動作により元のスケジューラ上で処理が継続する。
  std::println("step3 main#{}", std::this_thread::get_id());
}

ex::task<void, TaskEnv> g(ex::scheduler auto sch)
{
  std::println("step1 main#{}", std::this_thread::get_id());

  // スケジューラを変更してサブタスクを実行
  co_await (ex::schedule(sch) | ex::then([]{
    std::println("step2 worker#{}", std::this_thread::get_id());
  }));

  // inline_schedulerを持つタスクコルーチンのco_await式では、
  // コルーチンの再開(resume)時に再スケジューリングが行われない。
  // このためco_await式内で変更したスケジューラが引き継がれる。
  std::println("step3 worker#{}", std::this_thread::get_id());
}

int main()
{
  // ワーカースレッドを開始
  ex::run_loop loop;
  std::jthread worker{[&]{
    loop.run();
  }};
  auto sch = loop.get_scheduler();

  std::println("task_scheduler(default)");
  std::this_thread::sync_wait( f(sch) );

  std::println("inline_scheduler");
  std::this_thread::sync_wait( g(sch) );

  loop.finish();
}

出力例

task_scheduler(default)
step1 main#124468393588544
step2 worker#124468391311040
step3 main#124468393588544
inline_scheduler
step1 main#124468393588544
step2 worker#124468391311040
step3 worker#124468391311040

バージョン

言語

  • C++26

処理系

関連項目

参照