执行控制库 (C++26 起)
来自cppreference.com
< cpp
执行控制库提供了用于在通用执行资源上管理异步执行的框架。
该库的目标是提供针对异步操作的基本术语类型,并允许以简便和可组合的方式构建任务执行图。
目录 |
[编辑] 库范围的定义
- 发送器:对要发送去执行的工作的描述。产生操作状态(见下文)。
- 发送器将它们的结果异步“发送”给称为“接收器”(见下文)的监听者。
- 可以用通用算法把发送器组合成任务图。
- 发送器工厂/适配器是捕捉了满足 sender 概念的对象中的常见异步模式的通用算法。
- 接收器:泛化的回调,它消耗或“接受”由发送器产生的异步结果。
- 接收器包含三个不同“通道”,发送器可以通过它们传播成功、失败和取消的结果,分别称为“值”、“错误”和“停止”通道。
- 接收器提供可扩展的执行环境:可以由消耗方用来参数化异步操作的一组键/值对。
- 操作状态:包含异步操作所需状态的对象。
- 当发送器和接收器被传递给 std::execution::connect 时,就被连接起来。
- 将发送器和接收器连接起来的结果就是一个操作状态。
- 当在操作状态上调用“
start
”后,其工作才会加入队列执行。 - 一旦启动,则操作状态的生存期在异步操作完成前都不会结束,且其地址必须稳定。
- 调度器:对执行上下文的轻量级句柄。
- 执行上下文是诸如线程池或 GPU 流这样的异步执行源。
- 调度器是工厂或发送器,它在执行上下文所拥有的某个执行线程中完成其接收器。
[编辑] 库工具
[编辑] 概念
[编辑] 调度器
在标头
<execution> 定义 | |
在命名空间
std::execution 定义 | |
(C++26) |
指定类型为调度器 (概念) |
[编辑] 发送器
在标头
<execution> 定义 | |
在命名空间
std::execution 定义 | |
(C++26) |
指定类型为发送器 (概念) |
(C++26) |
指定发送器可以为给定关联环境类型创建异步操作 (概念) |
(C++26) |
指定发送器可以连接到特定的接收器类型 (概念) |
[编辑] 接收器
在标头
<execution> 定义 | |
在命名空间
std::execution 定义 | |
(C++26) |
指定类型为接收器 (概念) |
(C++26) |
指定类型为适于给定完成签名的接收器 (概念) |
[编辑] 操作状态
在标头
<execution> 定义 | |
在命名空间
std::execution 定义 | |
(C++26) |
指定类型为操作状态 (概念) |
[编辑] 工具组件
[编辑] 执行上下文
在标头
<execution> 定义 | |
在命名空间
std::execution 定义 | |
(C++26) |
保有一个线程安全 MPSC 任务队列和一个手动驱动时间循环的执行资源 (类) |
[编辑] 执行域
在标头
<execution> 定义 | |
在命名空间
std::execution 定义 | |
(C++26) |
默认执行域标签类型,用于派发源于发送器标签的变换 (类) |
(C++26) |
变换为给定执行域标签下的新发送器 (函数模板) |
(C++26) |
变换为给定执行域标签下的新可查询对象 (函数模板) |
(C++26) |
在给定执行域标签下使用给定发送器消耗器标签和一组实参来消耗一个发送器并返回其结果 (函数模板) |
[编辑] 向前进展保证
在标头
<execution> 定义 | |
在命名空间
std::execution 定义 | |
指定由调度器的关联执行资源所创建的执行代理的向前进展保证 (枚举) |
[编辑] 环境
在标头
<execution> 定义 | |
在命名空间
std::execution 定义 | |
(C++26) |
以查询对象和值构建可查询对象 (类模板) |
(C++26) |
聚合多个可查询对象为一个可查询对象 (类模板) |
(C++26) |
返回给定实参的关联可查询对象 (定制点对象) |
[编辑] 查询
在标头
<execution> 定义 | |
(C++26) |
询问查询对象是否应当通过可查询适配器予以转发 (定制点对象) |
(C++26) |
询问可查询对象的关联分配器 (定制点对象) |
(C++26) |
询问可查询对象的关联停止令牌 (定制点对象) |
(C++26) |
询问可查询对象的关联执行域标签 (定制点对象) |
(C++26) |
询问可查询对象的关联调度器 (定制点对象) |
询问可查询对象以获得可用于为向前进展委托目的而向之委托工作的调度器 (定制点对象) | |
从发送器的属性中获取与某个完成标签关联的完成调度器 (定制点对象) | |
询问调度器的 execution::forward_progress_guarantee (定制点对象) |
[编辑] 完成签名
在标头
<execution> 定义 | |
在命名空间
std::execution 定义 | |
编码一组完成签名的集合的类型 (类模板) | |
获得发送器的完成签名 (定制点对象) | |
变换一个完成签名集合为另一个集合 (别名模板) | |
变换发送器的完成签名 (别名模板) | |
(C++26) |
获得发送器的标签类型 (别名模板) |
(C++26) |
获得发送器的值完成类型 (别名模板) |
(C++26) |
获得发送器的错误完成类型 (别名模板) |
(C++26) |
确定发送器是否支持停止完成 (变量模板) |
[编辑] 协程工具
在标头
<execution> 定义 | |
在命名空间
std::execution 定义 | |
(C++26) |
变换表达式为特定协程中的可等待对象 (定制点对象) |
当用作协程承诺类型的基类时,使发送器在该协程类型之中可等待 (类模板) |
[编辑] 核心操作
[编辑] 操作状态
在标头
<execution> 定义 | |
在命名空间
std::execution 定义 | |
(C++26) |
连接 sender 和 receiver (定制点对象) |
(C++26) |
启动与某 operation_state 对象关联的异步操作 (定制点对象) |
[编辑] 完成函数
这些函数由发送器调用,以向它们的接收器告知工作完成。
在标头
<execution> 定义 | |
在命名空间
std::execution 定义 | |
(C++26) |
值完成函数,指出已成功完成 (定制点对象) |
(C++26) |
错误完成函数,指出计算或调度时发生了错误 (定制点对象) |
(C++26) |
停止完成函数,指出操作在能够达成成功或失败之前就已结束 (定制点对象) |
[编辑] 发送器算法
本节未完成 原因:WIP update to current standard in progress |
[编辑] 发送器工厂
发送器工厂是返回发送器的函数,且其形参具有使得概念 sender
为 false 的类型。
以下为发送器工厂:
在标头
<execution> 定义 | |
在命名空间
std::execution 定义 | |
(C++26) |
接受一组可变数量的实参并返回一个发送器,当它被连接并启动时,将通过把各实参传递给接收器的值完成函数而同步地完成 (定制点对象) |
(C++26) |
接受单个实参并返回一个发送器,当它被连接并启动时,将通过把实参传递给接收器的错误完成函数而同步地完成 (定制点对象) |
(C++26) |
创建发送器,它通过调用其接收器的 set_stopped 立即完成 (定制点对象) |
(C++26) |
创建发送器,它查询其接收器的关联环境 (定制点对象) |
(C++26) |
准备一个要在给定调度器上执行的任务图 (定制点对象) |
[编辑] 可连接管道的发送器适配器
在标头
<execution> 定义 | |
在命名空间
std::execution 定义 | |
用于定义可连管道发送器适配器闭包对象的辅助基类模板 (类模板) |
[编辑] 发送器适配器
发送器适配器是返回发送器的函数,且它包含至少一个形参的类型满足 sender
概念,且所返回的发送器是此适配器函数的发送器实参的父发送器。
以下为发送器适配器:
在标头
<execution> 定义 | |
在命名空间
std::execution 定义 | |
(C++26) |
适配所提供发送器为在所提供调度器的执行支援上启动一次执行的发送器 (定制点对象) |
(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) |
返回将停止通道映射为一个错误的发送器 (定制点对象) |
[编辑] 发送器消耗器
发送器消耗器是一种算法,它接受一个或多个发送器为参数且并不返回发送器。
在标头
<execution> 定义 | |
在命名空间
std::this_thread 定义 | |
(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; }
输出:
hello world
[编辑] 参阅
(C++11) |
异步运行一个函数(有可能在新线程中执行),并返回将保有它的结果的 std::future (函数模板) |