名前空間
変種
操作

std::execution::scheduler

From cppreference.com
< cpp‎ | execution
 
 
 
ヘッダ <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以降)
Helper tag type
struct scheduler_t {};
(2) (C++26以降)

Concept scheduler は、C++実行ライブラリで動作するスレッドプールなどの実行リソースへの軽量ハンドラである「スケジューラ」を表す型によってモデル化されます。

[edit] 意味要件

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

スケジューラのコピーコンストラクタ、デストラクタ、等価比較、またはスワップメンバ関数は非例外的である必要があります。

これらのメンバ関数すべて、およびスケジューラ型の 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 から返されたセーダーオブジェクトに接続されたレシーバの保留中の完了をブロックしてはなりません(基盤となるリソースは、サブミットされた関数オブジェクトの完了を待機するための個別のAPIを提供する場合があります)。

[edit]

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

[edit] 関連項目

指定されたスケジューラで実行するためのタスクグラフを準備します。
(カスタマイズポイントオブジェクト)[edit]
English 日本語 中文(简体) 中文(繁體)