std::execution::scheduler
来自cppreference.com
<tbody>
</tbody>
| 在标头 <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 函数都必须是线程安全的。
仅当两个调度器表示同一个执行资源时,它们相等。
对于给定调度器 sch,表达式 get_completion_scheduler<set_value_t>(get_env(schedule(sch))) 与 sch 比较为相等。
对于给定调度器 sch,如果表达式 get_domain(sch) 良构,那么表达式 get_domain(get_env(schedule(sch))) 也良构且具有相同类型。
调度器的析构函数,不能阻塞于任何与 schedule 返回的发送器对象向连接的接收器的完成(底层资源可以提供单独 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 << "回到主线程,结果为 " << i << '\n';
}
输出:
Hello world! Have an int.
回到主线程,结果为 55
参阅
(C++26) |
准备一个要在给定调度器上执行的任务图 (定制点对象) |