当前位置: 首页 > news >正文

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

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

多个异常

如果任务或并行算法接收到多个异常,则运行时仅将其中一个异常封送到调用上下文。 运行时不保证它会封送哪个异常。

以下示例使用 parallel_for 算法将数字打印到控制台。 如果输入值小于某个最小值或大于某个最大值,则会引发异常。 在此示例中,多个工作函数可以引发异常。

// eh-multiple.cpp
// compile with: /EHsc
#include <ppl.h>
#include <iostream>
#include <sstream>using namespace concurrency;
using namespace std;int wmain()
{const int min = 0;const int max = 10;// Print values in a parallel_for loop. Use a try-catch block to // handle any exceptions that occur in the loop.try{parallel_for(-5, 20, [min,max](int i){// Throw an exeception if the input value is less than the // minimum or greater than the maximum.// Otherwise, print the value to the console.if (i < min){stringstream ss;ss << i << ": the value is less than the minimum.";throw exception(ss.str().c_str());}else if (i > max){stringstream ss;ss << i << ": the value is greater than than the maximum.";throw exception(ss.str().c_str());}else{wstringstream ss;ss << i << endl;wcout << ss.str();}});}catch (exception& e){// Print the error to the console.wcerr << L"Caught exception: " << e.what() << endl;}  
}输出为:
8293104567Caught exception: -5: the value is less than the minimum.
轻量级任务

轻量级任务是直接从 concurrency::Scheduler 对象计划的任务。 轻量级任务的开销比普通任务少。 但是,运行时不会捕获轻量级任务引发的异常。 相反,异常将被未经处理的异常处理程序捕获,默认情况下会终止进程。 因此,在你的应用程序中使用适当的错误处理机制。

异步代理

与轻量级任务一样,运行时不管理由异步代理引发的异常。

以下示例显示了一种处理派生自 concurrency::agent 的类中的异常的方法。 这个例子定义了 points_agent 类。 points_agent::run 方法从消息缓冲区中读取 point 对象并将它们打印到控制台。 如果 run 方法接收到 NULL 指针,则会引发异常。

run 方法的所有工作都是围绕一个 try-catch 块。 catch 块将异常存储在消息缓冲区中。 应用程序通过在代理完成后读取此缓冲区来检查代理是否遇到错误。

// eh-agents.cpp
// compile with: /EHsc
#include <agents.h>
#include <iostream>using namespace concurrency;
using namespace std;// Defines a point with x and y coordinates.
struct point
{int X;int Y;
};// Informs the agent to end processing.
point sentinel = {0,0};// An agent that prints point objects to the console.
class point_agent : public agent
{
public:explicit point_agent(unbounded_buffer<point*>& points): _points(points){ }// Retrieves any exception that occurred in the agent.bool get_error(exception& e){return try_receive(_error, e);}protected:// Performs the work of the agent.void run(){// Perform processing in a try block.try{// Read from the buffer until we reach the sentinel value.while (true){// Read a value from the message buffer.point* r = receive(_points);// In this example, it is an error to receive a // NULL point pointer. In this case, throw an exception.if (r == NULL){throw exception("point must not be NULL");}// Break from the loop if we receive the // sentinel value.else if (r == &sentinel){break;}// Otherwise, do something with the point.else{// Print the point to the console.wcout << L"X: " << r->X << L" Y: " << r->Y << endl;}}}// Store the error in the message buffer.catch (exception& e){send(_error, e);}// Set the agent status to done.done();}private:// A message buffer that receives point objects.unbounded_buffer<point*>& _points;// A message buffer that stores error information.single_assignment<exception> _error;
};int wmain()
{  // Create a message buffer so that we can communicate with// the agent.unbounded_buffer<point*> buffer;// Create and start a point_agent object.point_agent a(buffer);a.start();// Send several points to the agent.point r1 = {10, 20};point r2 = {20, 30};point r3 = {30, 40};send(buffer, &r1);send(buffer, &r2);// To illustrate exception handling, send the NULL pointer to the agent.send(buffer, reinterpret_cast<point*>(NULL));send(buffer, &r3);send(buffer, &sentinel);// Wait for the agent to finish.agent::wait(&a);// Check whether the agent encountered an error.exception e;if (a.get_error(e)){cout << "error occurred in agent: " << e.what() << endl;}// Print out agent status.wcout << L"the status of the agent is: ";switch (a.status()){case agent_created:wcout << L"created";break;case agent_runnable:wcout << L"runnable";break;case agent_started:wcout << L"started";break;case agent_done:wcout << L"done";break;case agent_canceled:wcout << L"canceled";break;default:wcout << L"unknown";break;}wcout << endl;
}

输出如下:

X: 10 Y: 20
X: 20 Y: 30
error occurred in agent: point must not be NULL
the status of the agent is: done

由于 try-catch 块存在于 while 循环之外,因此代理在遇到第一个错误时结束处理。 如果 try-catch 块在 while 循环内,则代理将在发生错误后继续。

此示例将异常存储在消息缓冲区中,以便另一个组件可以在代理运行时监控代理是否存在错误。 此示例使用 concurrency::single_assignment 对象来存储错误。 在代理处理多个异常的情况下,single_assignment 类仅存储传递给它的第一条消息。 要仅存储最后一个异常,请使用 concurrency::overwrite_buffer 类。 要存储所有异常,请使用 concurrency::unbounded_buffer 类。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 关于一个早期的计算机网络的理解
  • JAVAEE初阶第二节——多线程基础(上)
  • 数据结构--初步了解(抽象分级)
  • win11快捷键配置
  • 探索 Zed 编辑器:速度与协作的巅峰之作
  • Rainbond 国内最靠谱 docker.rainbond.cc 拉取 dockerhub 容器镜像
  • 中国电力建设集团有限公司 PK 中国能源建设集团有限公司
  • 第七章 用函数实现模块化程序设计
  • 扭矩传感器计量校准常会有哪些问题出现?具体处理办法是什么?
  • 什么软件可以用平板远程控制电脑?
  • PHP一键创建全球参与探索现代在线投票系统
  • 如何通过Spring Cloud Consul增强微服务安全性和可靠性
  • 代码随想录---算法训练营---总结
  • 苹果M4芯片Mac全面曝光 或10月发布
  • 泰克Tektronix TDP1500,TDP3500,TDP4000差分探头
  • 「译」Node.js Streams 基础
  • 【知识碎片】第三方登录弹窗效果
  • android 一些 utils
  • Java 11 发布计划来了,已确定 3个 新特性!!
  • JavaScript实现分页效果
  • Java新版本的开发已正式进入轨道,版本号18.3
  • node 版本过低
  • SegmentFault 2015 Top Rank
  • SegmentFault 社区上线小程序开发频道,助力小程序开发者生态
  • select2 取值 遍历 设置默认值
  • windows-nginx-https-本地配置
  • 记一次删除Git记录中的大文件的过程
  • 实现菜单下拉伸展折叠效果demo
  • 写代码的正确姿势
  • Redis4.x新特性 -- 萌萌的MEMORY DOCTOR
  • 我们雇佣了一只大猴子...
  • ​14:00面试,14:06就出来了,问的问题有点变态。。。
  • # 深度解析 Socket 与 WebSocket:原理、区别与应用
  • #java学习笔记(面向对象)----(未完结)
  • #Linux(make工具和makefile文件以及makefile语法)
  • ( 用例图)定义了系统的功能需求,它是从系统的外部看系统功能,并不描述系统内部对功能的具体实现
  • (2.2w字)前端单元测试之Jest详解篇
  • (8)Linux使用C语言读取proc/stat等cpu使用数据
  • (pt可视化)利用torch的make_grid进行张量可视化
  • (WSI分类)WSI分类文献小综述 2024
  • (安全基本功)磁盘MBR,分区表,活动分区,引导扇区。。。详解与区别
  • (附源码)php新闻发布平台 毕业设计 141646
  • (四)stm32之通信协议
  • (新)网络工程师考点串讲与真题详解
  • *++p:p先自+,然后*p,最终为3 ++*p:先*p,即arr[0]=1,然后再++,最终为2 *p++:值为arr[0],即1,该语句执行完毕后,p指向arr[1]
  • .net core webapi Startup 注入ConfigurePrimaryHttpMessageHandler
  • .NET Framework、.NET Core 、 .NET 5、.NET 6和.NET 7 和.NET8 简介及区别
  • .NET Framework与.NET Framework SDK有什么不同?
  • .NET 直连SAP HANA数据库
  • .net6 webapi log4net完整配置使用流程
  • /etc/X11/xorg.conf 文件被误改后进不了图形化界面
  • []常用AT命令解释()
  • [240621] Anthropic 发布了 Claude 3.5 Sonnet AI 助手 | Socket.IO 拒绝服务漏洞
  • [C#]使用PaddleInference图片旋转四种角度检测
  • [C++随笔录] 红黑树