执行控制库 (自 C++26 起)
来自 cppreference.cn
< 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) |
将表达式转换为特定协程内的可等待对象 (定制点对象) |
当用作协程 promise 类型的基类时,使发送器在该协程类型内可等待 (类模板) |
[编辑] 核心操作
[编辑] 操作状态
定义于头文件
<execution> | |
定义于命名空间
std::execution | |
(C++26) |
将 sender 与 receiver 连接(定制点对象) |
(C++26) |
启动与 operation_state 对象关联的异步操作(定制点对象) |
[编辑] 完成函数
这些函数由发送器调用,以向其接收器宣告工作完成。
定义于头文件
<execution> | |
定义于命名空间
std::execution | |
(C++26) |
值完成函数,指示成功完成 (定制点对象) |
(C++26) |
错误完成函数,指示在计算或调度期间发生错误 (定制点对象) |
(C++26) |
停止完成函数,指示操作在能够实现成功或失败之前结束 (定制点对象) |
[编辑] 发送器算法
本节内容不完整 原因:正在进行 WIP 更新以符合当前标准 |
[编辑] 发送器工厂
发送器工厂是一个返回发送器的函数,其参数类型为 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,该 future 将保存结果 (函数模板) |