windows C++ 并行编程-PPL 中的取消操作(三)

embedded/2024/9/23 4:27:01/

并行模式库 (PPL) 中取消操作的角色、如何取消并行工作以及如何确定取消并行工作的时间。

运行时使用异常处理实现取消操作。 请勿在代码中捕捉或处理这些异常。 此外,还建议你在任务的函数体中编写异常安全的代码。 例如,可以使用获取资源即初始化 (RAII) 模式,以确保在任务体中引发异常时正确处理资源。

使用取消方法来取消并行工作

concurrency::task_group::cancel 和 concurrency::structured_task_group::cancel 方法可将任务组设置为已取消状态。 在你调用 cancel 之后,任务组不会启动将来的任务。 cancel 方法可以由多个子任务调用。 已取消状态会导致 concurrency::task_group::wait 和 concurrency::structured_task_group::wait 方法返回 concurrency::canceled。

如果任务组已取消,从每个子任务到运行时的调用可以触发一个中断点,这将导致运行时引发和捕获内部异常类型以取消活动任务。 并发运行时不定义具体的中断点;它们可以在对运行时的任何调用中出现。 运行时必须处理它引发的异常才能执行取消。 因此,不要处理任务正文中的未知异常。

如果子任务执行耗时的操作,并且不会调入运行时,它必须定期检查取消并及时退出。 下面的示例演示一种确定取消工作的时间的方法。 任务 t4 在遇到错误时取消父任务组。 任务 t5 偶尔调用 structured_task_group::is_canceling 方法来检查取消。 如果父任务组已取消,则任务 t5 打印一条消息并退出。

structured_task_group tg2;// Create a child task.
auto t4 = make_task([&] {// Perform work in a loop.for (int i = 0; i < 1000; ++i){// Call a function to perform work.// If the work function fails, cancel the parent task// and break from the loop.bool succeeded = work(i);if (!succeeded){tg2.cancel();break;}}
});// Create a child task.
auto t5 = make_task([&] {// Perform work in a loop.for (int i = 0; i < 1000; ++i){// To reduce overhead, occasionally check for // cancelation.if ((i%100) == 0){if (tg2.is_canceling()){wcout << L"The task was canceled." << endl;break;}}// TODO: Perform work here.}
});// Run the child tasks and wait for them to finish.
tg2.run(t4);
tg2.run(t5);
tg2.wait();

此示例在任务循环每迭代 100 次时检查是否取消。 检查取消的频率取决于任务执行的工作量和你需要任务响应取消的速度。

如果你无权访问父任务组对象,请调用 concurrency::is_current_task_group_canceling 函数以确定是否已取消父任务组。

cancel 方法只影响子任务。 例如,如果取消并行工作树插图中的任务组 tg1,则该树中的所有任务(t1、t2、t3、t4 和 t5)都将受到影响。 如果取消嵌套的任务组 tg2,则只有任务 t4 和 t5 会受到影响。

当你调用 cancel 方法时,将同时取消所有子任务组。 但是,取消操作并不影响并行工作树中任务组的任何父级。 下面的示例通过在并行工作树插图中进行生成来演示这一点。

这些示例中的第一个示例为任务 t4(该任务是任务组 tg2 的子级)创建一个工作函数。 该工作函数在循环中调用函数 work。 如果对 work 的任何调用失败,则该任务取消其父任务组。 这将导致任务组 tg2 进入已取消状态,但不会取消任务组 tg1。

auto t4 = make_task([&] {// Perform work in a loop.for (int i = 0; i < 1000; ++i){// Call a function to perform work.// If the work function fails, cancel the parent task// and break from the loop.bool succeeded = work(i);if (!succeeded){tg2.cancel();break;}}         
});

此第二个示例与第一个示例类似,只不过该任务将取消任务组 tg1。 这会影响树中的所有任务(t1、t2、t3、t4 和 t5)。

auto t4 = make_task([&] {// Perform work in a loop.for (int i = 0; i < 1000; ++i){// Call a function to perform work.// If the work function fails, cancel all tasks in the tree.bool succeeded = work(i);if (!succeeded){tg1.cancel();break;}}   
});

structured_task_group 类不是线程安全的。 因此,调用其父 structured_task_group 对象方法的子任务会产生未指定的行为。 此规则的例外是 structured_task_group::cancel 和 concurrency::structured_task_group::is_canceling 方法。 子任务可以调用这些方法来取消父任务组和检查取消。

 注意尽管可以使用取消标记来取消由作为 task 对象的子级运行的任务组执行的工作,但不能使用 task_group::cancel 或 structured_task_group::cancel 方法来取消任务组中运行的 task 对象。


http://www.ppmy.cn/embedded/112804.html

相关文章

C++ 科目二 智能指针 [weak_ptr] (解决shared_ptr的循环引用问题)

shared_ptr引入的重复计数问题&#xff0c;导致内存泄漏 using namespace std; class CFather; class CSon;class CFather { public:CFather(){}void Set(shared_ptr<CSon> pson){Pson pson;}shared_ptr<CSon> Pson; };class CSon { public:CSon(){}void Set(sha…

JVM字节码与局部变量表

文章目录 局部变量表javap字节码指令分类 指令指令数据类型前缀加载和存储指令加载常量算术指令其他指令 字节码示例说明 局部变量表 每个线程的帧栈是独立的&#xff0c;每个线程中的方法调用会产生栈帧&#xff0c;栈帧中保存着方法执行的信息&#xff0c;例如局部变量表。 …

vue2,3生命周期

Vue.js 的生命周期在 Vue 2 和 Vue 3 中有所不同&#xff0c;但基本的概念是相似的。Vue 的生命周期是指 Vue 实例从创建到销毁的整个过程&#xff0c;这个过程中 Vue 实例会触发一系列的事件&#xff0c;我们称之为生命周期钩子&#xff08;Lifecycle Hooks&#xff09;。开发…

简单了解Maven与安装

Maven 1.Maven 简介 Maven 是 Apache 软件基金会&#xff08;国外组织&#xff0c;专门维护开源项目&#xff09;的一个开源项目, 是一个优秀的项目构建工具, 它用来帮助开发者管理项目中的 jar, 以及 jar 之间的依赖关系(在A.jar文件中用到了B.jar)、 完成项目的编译&am…

OpenAI O1:人工智能推理能力的新里程碑

引言 北京时间9月13日凌晨&#xff0c;OpenAI在没有任何预告的情况下&#xff0c;正式发布了其首款具有推理能力的模型——OpenAI O1。这一模型的发布&#xff0c;不仅标志着人工智能能力的新水平&#xff0c;也预示着AI技术发展的新范式。本文将详细解析OpenAI O1模型的技术特…

【Java】线程状态:线程生命周期的六个阶段

欢迎浏览高耳机的博客 希望我们彼此都有更好的收获 感谢三连支持&#xff01; 在Java中&#xff0c;线程可以处于多种状态&#xff0c;这些状态描述了线程的生命周期。了解这些状态及其转换条件对于编写高效且无错误的多线程应用程序至关重要。本文将总结Java线程的几种状态&am…

单组件的编写

项目搭好了&#xff0c;第一个需要了解的是 Vue 组件的变化&#xff0c;由于这部分篇幅会非常大&#xff0c;所以会分成很多个小节&#xff0c;一部分一部分按照开发顺序来逐步了解。 因为 Vue 3 对 TypeScript 的支持真的是太完善了&#xff0c;并且 TypeScript 的发展趋势和…

从零开始搭建 PHP

&#x1f6e0;️ 从零开始搭建 PHP 环境&#xff1a;详细教程 PHP&#xff08;Hypertext Preprocessor&#xff09;是最流行的后端脚本语言之一&#xff0c;广泛用于构建动态网站和 Web 应用程序。在开始 PHP 开发之前&#xff0c;首先需要搭建 PHP 运行环境。无论你使用的是 …