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

相关文章

c++中std::placeholders的使用方法

《c++中std::placeholders的使用方法》std::placeholders是C++标准库中的一个工具,用于在函数对象绑定时创建占位符,本文就来详细的介绍一下,具有一定的参考价值,感兴... 目录1. 基本概念2. 使用场景3. 示例示例 1:部分参数绑定示例 2:参数重排序4. 注意事项5.

使用C++将处理后的信号保存为PNG和TIFF格式

《使用C++将处理后的信号保存为PNG和TIFF格式》在信号处理领域,我们常常需要将处理结果以图像的形式保存下来,方便后续分析和展示,C++提供了多种库来处理图像数据,本文将介绍如何使用stb_ima... 目录1. PNG格式保存使用stb_imagephp_write库1.1 安装和包含库1.2 代码解

Windows设置nginx启动端口的方法

《Windows设置nginx启动端口的方法》在服务器配置与开发过程中,nginx作为一款高效的HTTP和反向代理服务器,被广泛应用,而在Windows系统中,合理设置nginx的启动端口,是确保其正... 目录一、为什么要设置 nginx 启动端口二、设置步骤三、常见问题及解决一、为什么要设置 nginx

C++实现封装的顺序表的操作与实践

《C++实现封装的顺序表的操作与实践》在程序设计中,顺序表是一种常见的线性数据结构,通常用于存储具有固定顺序的元素,与链表不同,顺序表中的元素是连续存储的,因此访问速度较快,但插入和删除操作的效率可能... 目录一、顺序表的基本概念二、顺序表类的设计1. 顺序表类的成员变量2. 构造函数和析构函数三、顺序表

使用C++实现单链表的操作与实践

《使用C++实现单链表的操作与实践》在程序设计中,链表是一种常见的数据结构,特别是在动态数据管理、频繁插入和删除元素的场景中,链表相比于数组,具有更高的灵活性和高效性,尤其是在需要频繁修改数据结构的应... 目录一、单链表的基本概念二、单链表类的设计1. 节点的定义2. 链表的类定义三、单链表的操作实现四、

C#使用DeepSeek API实现自然语言处理,文本分类和情感分析

《C#使用DeepSeekAPI实现自然语言处理,文本分类和情感分析》在C#中使用DeepSeekAPI可以实现多种功能,例如自然语言处理、文本分类、情感分析等,本文主要为大家介绍了具体实现步骤,... 目录准备工作文本生成文本分类问答系统代码生成翻译功能文本摘要文本校对图像描述生成总结在C#中使用Deep

C#多线程编程中导致死锁的常见陷阱和避免方法

《C#多线程编程中导致死锁的常见陷阱和避免方法》在C#多线程编程中,死锁(Deadlock)是一种常见的、令人头疼的错误,死锁通常发生在多个线程试图获取多个资源的锁时,导致相互等待对方释放资源,最终形... 目录引言1. 什么是死锁?死锁的典型条件:2. 导致死锁的常见原因2.1 锁的顺序问题错误示例:不同

Spring Boot 整合 ShedLock 处理定时任务重复执行的问题小结

《SpringBoot整合ShedLock处理定时任务重复执行的问题小结》ShedLock是解决分布式系统中定时任务重复执行问题的Java库,通过在数据库中加锁,确保只有一个节点在指定时间执行... 目录前言什么是 ShedLock?ShedLock 的工作原理:定时任务重复执行China编程的问题使用 Shed

使用C/C++调用libcurl调试消息的方式

《使用C/C++调用libcurl调试消息的方式》在使用C/C++调用libcurl进行HTTP请求时,有时我们需要查看请求的/应答消息的内容(包括请求头和请求体)以方便调试,libcurl提供了多种... 目录1. libcurl 调试工具简介2. 输出请求消息使用 CURLOPT_VERBOSE使用 C

C++实现获取本机MAC地址与IP地址

《C++实现获取本机MAC地址与IP地址》这篇文章主要为大家详细介绍了C++实现获取本机MAC地址与IP地址的两种方式,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 实际工作中,项目上常常需要获取本机的IP地址和MAC地址,在此使用两种方案获取1.MFC中获取IP和MAC地址获取