windows C++ 并行编程-并发的异常处理(二)

2024-09-03 08:12

本文主要是介绍windows C++ 并行编程-并发的异常处理(二),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

并发运行时使用 C++ 异常处理来传达多种错误。 这些错误包括:无效使用运行时、无法获取资源等运行时错误,以及你提供给任务和任务组的工作函数中发生的错误。 当任务或任务组引发异常时,运行时会保存该异常并将其编组到等待任务或任务组完成的上下文。 对于轻量级任务和代理等组件,运行时不会为你管理异常。 在这些情况下,你必须实现自己的异常处理机制。 本系列中描述运行时如何处理任务、任务组、轻量级任务和异步代理引发的异常,以及如何在应用程序中响应异常。

任务组和并行算法

本节介绍运行时如何处理任务组引发的异常。 本节也适用于并行算法,例如 concurrency::parallel_for,因为这些算法建立在任务组之上。

确保你了解异常对相关任务的影响。 有关如何对任务或并行算法使用异常处理的推荐实践,请参阅“并行模式库中的最佳实践”主题中的了解取消和异常处理如何影响对象销毁一节。

在传递给 concurrency::task_group 或 concurrency::structured_task_group 对象的工作函数的主体中引发异常时,运行时会存储该异常并将其封送到调用 concurrency::task_group::wait、concurrency::structured_task_group::wait、concurrency::task_group::run_and_wait 或 concurrency::structured_task_group::run_and_wait 的上下文中。 运行时还会停止任务组中的所有活动任务(包括子任务组中的任务),并丢弃任何尚未启动的任务。

以下示例显示了引发异常的工作函数的基本结构。 该示例使用一个 task_group 对象并行打印两个 point 对象的值。 print_point 工作函数将 point 对象的值打印到控制台。 如果输入值为 NULL,则工作函数会引发异常。 运行时存储此异常并将其封送到调用 task_group::wait 的上下文中。

// eh-task-group.cpp
// compile with: /EHsc
#include <ppl.h>
#include <iostream>
#include <sstream>using namespace concurrency;
using namespace std;// Defines a basic point with X and Y coordinates.
struct point
{int X;int Y;
};// Prints the provided point object to the console.
void print_point(point* pt)
{// Throw an exception if the value is NULL.if (pt == NULL){throw exception("point is NULL.");}// Otherwise, print the values of the point.wstringstream ss;ss << L"X = " << pt->X << L", Y = " << pt->Y << endl;wcout << ss.str();
}int wmain()
{// Create a few point objects.point pt = {15, 30};point* pt1 = &pt;point* pt2 = NULL;// Use a task group to print the values of the points.task_group tasks;tasks.run([&] {print_point(pt1);});tasks.run([&] {print_point(pt2);});// Wait for the tasks to finish. If any task throws an exception,// the runtime marshals it to the call to wait.try{tasks.wait();}catch (const exception& e){wcerr << L"Caught exception: " << e.what() << endl;}
}输出为:
X = 15, Y = 30Caught exception: point is NULL.
运行时引发的异常

调用运行时可能会导致异常。 大多数异常类型(除了 concurrency::task_canceled 和 concurrency::operation_timed_out),都表示编程错误。 这些错误通常是不可恢复的,因此不应由应用程序代码捕获或处理。 我们建议你仅在需要诊断编程错误时才在应用程序代码中捕获或处理不可恢复的错误。 但是,了解运行时定义的异常类型可以帮助你诊断编程错误。

运行时引发的异常与工作函数引发的异常的异常处理机制相同。 例如,concurrency::receive 函数如果在指定时间段内没有收到消息,则会引发 operation_timed_out。 如果 receive 在传递给任务组的工作函数中引发异常,则运行时存储该异常并将其编组到调用 task_group::wait、structured_task_group::wait、task_group::run_and_wait 或 structured_task_group::run_and_wait 的上下文中。

以下示例使用 concurrency::parallel_invoke 算法并行运行两个任务。 第一个任务等待五秒钟,然后将消息发送到消息缓冲区。 第二个任务使用 receive 函数等待三秒钟以接收来自同一消息缓冲区的消息。 如果在该时间段内没有收到消息,receive 函数将引发 operation_timed_out。

// eh-time-out.cpp
// compile with: /EHsc
#include <agents.h>
#include <ppl.h>
#include <iostream>using namespace concurrency;
using namespace std;int wmain()
{single_assignment<int> buffer;int result;try{// Run two tasks in parallel.parallel_invoke(// This task waits 5 seconds and then sends a message to // the message buffer.[&] {wait(5000); send(buffer, 42);},// This task waits 3 seconds to receive a message.// The receive function throws operation_timed_out if it does // not receive a message in the specified time period.[&] {result = receive(buffer, 3000);});// Print the result.wcout << L"The result is " << result << endl;}catch (operation_timed_out&){wcout << L"The operation timed out." << endl;}
}输出为:
The operation timed out.

为防止应用程序异常终止,请确保你的代码在调用运行时时处理异常。 调用使用并发运行时的外部代码(例如第三方库)时,还要处理异常。

这篇关于windows C++ 并行编程-并发的异常处理(二)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1132494

相关文章

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关

【C++ Primer Plus习题】13.4

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream>#include "port.h"int main() {Port p1;Port p2("Abc", "Bcc", 30);std::cout <<

C++包装器

包装器 在 C++ 中,“包装器”通常指的是一种设计模式或编程技巧,用于封装其他代码或对象,使其更易于使用、管理或扩展。包装器的概念在编程中非常普遍,可以用于函数、类、库等多个方面。下面是几个常见的 “包装器” 类型: 1. 函数包装器 函数包装器用于封装一个或多个函数,使其接口更统一或更便于调用。例如,std::function 是一个通用的函数包装器,它可以存储任意可调用对象(函数、函数

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

06 C++Lambda表达式

lambda表达式的定义 没有显式模版形参的lambda表达式 [捕获] 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 有显式模版形参的lambda表达式 [捕获] <模版形参> 模版约束 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 含义 捕获:包含零个或者多个捕获符的逗号分隔列表 模板形参:用于泛型lambda提供个模板形参的名

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)