执行控制库 (C++26 起) - cppreference.com
执行控制库提供了用于在通用执行资源上管理异步执行的框架。
该库的目标是提供针对异步操作的基本术语类型,并允许以简便和可组合的方式构建任务执行图。
库范围的定义
- 发送器:对要发送去执行的工作的描述。产生操作状态(见下文)。
- 发送器将它们的结果异步“发送”给称为“接收器”(见下文)的监听者。
- 可以用通用算法把发送器组合成任务图。
- 发送器工厂/适配器是捕捉了满足 sender 概念的对象中的常见异步模式的通用算法。
- 接收器:泛化的回调,它消耗或“接受”由发送器产生的异步结果。
- 接收器包含三个不同“通道”,发送器可以通过它们传播成功、失败和取消的结果,分别称为“值”、“错误”和“停止”通道。
- 接收器提供可扩展的执行环境:可以由消耗方用来参数化异步操作的一组键/值对。
- 操作状态:包含异步操作所需状态的对象。
- 当发送器和接收器被传递给 std::execution::connect 时,就被连接起来。
- 将发送器和接收器连接起来的结果就是一个操作状态。
- 当在操作状态上调用“
start”后,其工作才会加入队列执行。 - 一旦启动,则操作状态的生存期在异步操作完成前都不会结束,且其地址必须稳定。
- 调度器:对执行上下文的轻量级句柄。
- 执行上下文是诸如线程池或 GPU 流这样的异步执行源。
- 调度器是工厂或发送器,它在执行上下文所拥有的某个执行线程中完成其接收器。
库工具
概念
调度器
发送器
接收器
操作状态
工具组件
执行上下文
执行域
向前进展保证
环境
查询
在标头 | |
(C++26) |
询问查询对象是否应当通过可查询适配器予以转发 (定制点对象) [编辑] |
(C++26) |
询问可查询对象的关联分配器 (定制点对象) [编辑] |
(C++26) |
询问可查询对象的关联停止令牌 (定制点对象) [编辑] |
(C++26) |
询问可查询对象的关联执行域标签 (定制点对象) [编辑] |
(C++26) |
询问可查询对象的关联调度器 (定制点对象) [编辑] |
| 询问接收器的环境:使用该接收器创建的操作状态将在哪个调度器上启动。 (定制点对象) [编辑] | |
| 询问可查询对象以获得可用于为向前进展委托目的而向之委托工作的调度器 (定制点对象) [编辑] | |
| 从发送器的属性中获取与某个完成标签关联的完成调度器 (定制点对象) [编辑] | |
| 询问调度器的 execution::forward_progress_guarantee (定制点对象) [编辑] | |
完成签名
在标头 | |
在命名空间 | |
| 编码一组完成签名的集合的类型 (类模板) [编辑] | |
| 获得发送器的完成签名 (定制点对象) [编辑] | |
(C++26) |
获得发送器的标签类型 (别名模板) [编辑] |
(C++26) |
获得发送器的值完成类型 (别名模板) [编辑] |
(C++26) |
获得发送器的错误完成类型 (别名模板) [编辑] |
(C++26) |
确定发送器是否支持停止完成 (变量模板) [编辑] |
协程工具
核心操作
操作状态
完成函数
这些函数由发送器调用,以向它们的接收器告知工作完成。
发送器算法
发送器工厂
发送器工厂是返回发送器的函数,且其形参具有使得概念 sender 为 false 的类型。
以下为发送器工厂:
在标头 | |
在命名空间 | |
(C++26) |
接受一组可变数量的实参并返回一个发送器,当它被连接并启动时,将通过把各实参传递给接收器的值完成函数而同步地完成 (定制点对象) [编辑] |
(C++26) |
接受单个实参并返回一个发送器,当它被连接并启动时,将通过把实参传递给接收器的错误完成函数而同步地完成 (定制点对象) [编辑] |
(C++26) |
创建发送器,它通过调用其接收器的 set_stopped 立即完成 (定制点对象) [编辑] |
(C++26) |
创建发送器,它查询其接收器的关联环境 (定制点对象) [编辑] |
(C++26) |
准备一个要在给定调度器上执行的任务图 (定制点对象) [编辑] |
可连接管道的发送器适配器
发送器适配器
发送器适配器是返回发送器的函数,且它包含至少一个形参的类型满足 sender 概念,且所返回的发送器是此适配器函数的发送器实参的父发送器。
以下为发送器适配器:
在标头 | |
在命名空间 | |
(C++26) |
适配所提供发送器为在所提供调度器的执行支援上启动一次执行的发送器 (定制点对象) [编辑] |
(C++26) |
适配所提供发送器为在所提供调度器的执行资源上完成的发送器 (定制点对象) [编辑] |
(C++26) |
适配所提供发送器为将执行转移到所提供调度器的执行资源以在其上运行发送器或继续,随后将执行转移回到原执行资源 (定制点对象) [编辑] |
(C++26) |
调度依赖于所提供发送器的完成的工作到所提供调度器的执行资源上 (定制点对象) [编辑] |
(C++26) |
以一个节点串联输入发送器的任务图,该节点表示以输入发送器所发送的各值为实参调用所提供的函数 (定制点对象) [编辑] |
(C++26) |
以一个节点串联输入发送器的任务图,该节点表示当发送错误时以输入发送器所发送的错误调用所提供的函数 (定制点对象) [编辑] |
(C++26) |
以一个节点串联输入发送器的任务图,该节点表示当被发送“停止”信号时以输入发送器的停止行为调用所提供的函数 (定制点对象) [编辑] |
(C++26) |
返回表示一个串联到输入发送器的节点的发送器,启动时,以输入发送器所发送的值为实参调用所提供的函数 (定制点对象) [编辑] |
(C++26) |
返回表示一个串联到输入发送器的节点的发送器,它以输入发送器的错误(若发生)调用所提供的函数 (定制点对象) [编辑] |
(C++26) |
返回表示一个串联到输入发送器上的节点的发送器,当发送了“停止”信号时,以输入发送器的停止令牌调用所提供的函数 (定制点对象) [编辑] |
| 创建一个多发发送器,它以所提供的形状中的每个索引和输入发送器所发送的值的来调用函数。该发送器在所有调用完成后,或发送错误时完成 (定制点对象) [编辑] | |
(C++26) |
适配多个输入发送器为一个当所有输入发送器都已完成时完成的发送器 (定制点对象) [编辑] |
| 适配多个输入发送器(每个都可能具有多个完成签名)为一个当所有输入发送器完成时完成的发送器 (定制点对象) [编辑] | |
(C++26) |
返回一个发送器,发送输入发送器发送的所有可能类型集合的元组的变体 (定制点对象) [编辑] |
返回将值通道映射为 std::optional<std::decay_t<T>> 并将停止通道映射为 std::nullopt 的发送器 (定制点对象) [编辑] | |
(C++26) |
返回将停止通道映射为一个错误的发送器 (定制点对象) [编辑] |
发送器消耗器
发送器消耗器是一种算法,它接受一个或多个发送器为参数且并不返回发送器。
示例
此示例的一个版本在 godbolt.org,它使用的是 stdexec,一个 std::execution 的实验性参考实现。
#include <cstdio> #include <execution> #include <string> #include <thread> #include <utility> using namespace std::literals; int main() { std::execution::run_loop loop; std::jthread worker([&](std::stop_token st) { std::stop_callback cb{st, [&]{ loop.finish(); }}; loop.run(); }); std::execution::sender auto hello = std::execution::just("hello world"s); std::execution::sender auto print = std::move(hello) | std::execution::then([](std::string msg) { return std::puts(msg.c_str()); }); std::execution::scheduler auto io_thread = loop.get_scheduler(); std::execution::sender auto work = std::execution::on(io_thread, std::move(print)); auto [result] = std::this_thread::sync_wait(std::move(work)).value(); return result; }
输出:
参阅
| 异步运行一个函数(有可能在新线程中执行),并返回将保有它的结果的 std::future (函数模板) [编辑] |