Namespaces
Variants

std::execution:: scheduler

From cppreference.net
定義済みヘッダー <execution>
template < class Sch >

concept scheduler =
std:: derived_from <
typename std:: remove_cvref_t < Sch > :: scheduler_concept ,
scheduler_t > &&
/*queryable*/ < Sch > &&
requires ( Sch && sch )
{
{
std :: execution :: schedule ( std:: forward < Sch > ( sch ) )
} - > std :: execution :: sender ;
{
auto (
std :: execution :: get_completion_scheduler <
std :: execution :: set_value_t > (
std :: execution :: get_env (
std :: execution :: schedule (
std:: forward < Sch > ( sch ) ) ) ) )
} - > std:: same_as < std:: remove_cvref_t < Sch >> ;
} &&
std:: equality_comparable < std:: remove_cvref_t < Sch >> &&
std:: copy_constructible < std:: remove_cvref_t < Sch >> ;

} ;
(1) (C++26以降)
ヘルパータグ型
struct scheduler_t { } ;
(2) (C++26以降)

scheduler という概念は、 スケジューラ である型によってモデル化されます。つまり、C++実行ライブラリと連携するスレッドプールなどの実行リソースへの軽量なハンドラです。

セマンティック要件

Sch のスケジューラと型 Env の実行環境が与えられ、 sender_in < schedule_result_t < Sch > , Env > が満たされる場合、 /*sender-in-of*/ < schedule_result_t < Sch > , Env > はモデル化される。

スケジューラのコピーコンストラクタ、デストラクタ、等価比較、またはswapメンバ関数は、例外を送出しないものでなければなりません。

これらのすべてのメンバー関数およびスケジューラ型の schedule 関数はスレッドセーフでなければなりません。

2つのスケジューラは、同じ実行リソースを表す場合にのみ等しくなります。

与えられたスケジューラ sch に対して、式 get_completion_scheduler < set_value_t > ( get_env ( schedule ( sch ) ) ) sch と等価である。

与えられたスケジューラ sch について、式 get_domain ( sch ) が well-formed である場合、式 get_domain ( get_env ( schedule ( sch ) ) ) も well-formed であり、同じ型を持ちます。

スケジューラのデストラクタは、scheduleから返されるsenderオブジェクトに接続された任意のレシーバーの完了が保留されている間、ブロックしてはならない(基盤リソースは、送信された関数オブジェクトの完了を待機するための別個のAPIを提供する場合がある)

std::execution::run_loop のシンプルなラッパーで、単一の専用スレッド上でrun_loopのキューを継続的にポーリングします。ドラフト参照実装を使用したデモ: https://godbolt.org/z/146fY4Y91

#include <execution>
#include <iostream>
#include <thread>
class single_thread_context
{
    std::execution::run_loop loop_{};
    std::jthread thread_;
public:
    single_thread_context()
        : thread_([this] { loop_.run(); })
    {}
    single_thread_context(single_thread_context&&) = delete;
    ~single_thread_context()
    {
        loop_.finish();
    }
    std::execution::scheduler auto get_scheduler() noexcept
    {
        return loop_.get_scheduler();
    }
};
int main()
{
    single_thread_context ctx;
    std::execution::sender auto snd =
        std::execution::schedule(ctx.get_scheduler())
        | std::execution::then([]
            {
                std::cout << "Hello world! Have an int.\n";
                return 015;
            })
        | std::execution::then([](int arg) { return arg + 42; });
    auto [i] = std::this_thread::sync_wait(snd).value();
    std::cout << "Back in the main thread, result is " << i << '\n';
}

出力:

Hello world! Have an int.
Back in the main thread, result is 55

関連項目

指定されたスケジューラ上で実行するためのタスクグラフを準備する
(カスタマイゼーションポイントオブジェクト)