首页 > 系统相关 >windows C++ 并行编程-并发的异常处理(三)

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

时间:2024-09-03 10:55:33浏览次数:9  
标签:point windows 编程 agent try buffer 任务 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 类。

标签:point,windows,编程,agent,try,buffer,任务,C++,异常
From: https://blog.csdn.net/m0_72813396/article/details/141539281

相关文章

  • 【最新原创毕设】基于微信小程序的老年人健康医疗信息服务平台设计+24246(免费领源码)可
    摘 要老年人健康是社会关注的重点之一,随着我国人口老龄化程度的增加,老年人的健康问题逐渐凸显。为了更好地满足老年人的健康需求,提高医疗服务质量和效率,开发一个基于SpringBoot的老年人健康医疗信息服务平台是十分必要的。老年人健康医疗信息服务平台利用Java语言,通过spring......
  • windows C++ 并行编程-并发的异常处理(二)
    并发运行时使用C++异常处理来传达多种错误。这些错误包括:无效使用运行时、无法获取资源等运行时错误,以及你提供给任务和任务组的工作函数中发生的错误。当任务或任务组引发异常时,运行时会保存该异常并将其编组到等待任务或任务组完成的上下文。对于轻量级任务和代理等组件......
  • C++学习笔记(四)类和对象
    类和对象C++对象模型和this指针成员变量和成员函数的存储C++中的成员变量和成员函数是分开存储的,只有非静态成员变量才属于类的对象上classPerson{intm_Age;//非静态成员变量staticintm_B;//静态成员变量voidfunc(){//不属于类的对象上}staticv......
  • c++入门基础
    欢迎来到c++入门基础的学习目录1、第一个c++程序2、命名空间3、c++的输入与输出4、缺省参数5、函数重载6、详解引用(引用属于重点知识)7、指针与引用的差别8、内联函数9、nullptr在学习c++之前我们要知道c++是什么—c++是c语言的扩展,主要在c语言之上添加了封装、继......
  • 10 Python面向对象编程:类和对象以及和Java的对比
    本篇是Python系列教程第10篇,更多内容敬请访问我的Python合集这里只介绍类和对象,self、属性、方法、访问控制、类继承、方法重写在后面的文章里介绍在Python中,类和对象是面向对象编程的基础。1类的概念类是一种创建对象的蓝图或模板。它定义了一组属性(变量)和方法(函......
  • 11 Python面向对象编程:三大特性,封装、继承、多态
    本篇是Python系列教程第11篇,更多内容敬请访问我的Python合集1封装封装就是把类的公有属性改成私有属性,并且提供对外访问的方法。示例classMyClass:def__init__(self,value):self.__value=valuedefget_value(self):returnself.__......
  • 大模型与编程
    大模型与编程在现代技术的发展中,大型语言模型(LargeLanguageModels,LLMs)和编程已经紧密结合,成为促进技术进步和实现业务目标的重要一环。无论是自动化代码生成、优化开发流程,还是提供智能化的技术支持,大模型在编程领域中的应用前景广阔。本文将深入探讨大模型与编程的结合,探讨它......
  • VMware Workstation 17.5.2 Pro for Linux 更新 OEM BIOS 2.7 支持 Windows Server 20
    VMwareWorkstation17.5.2ProforLinux更新OEMBIOS2.7支持WindowsServer2025VMwareWorkstation17.5.2PromacOSUnlocker&OEMBIOS2.7forLinux在Linux上运行macOSSonoma请访问原文链接:https://sysin.org/blog/vmware-workstation-17-unlocker-linux/,查......
  • VMware Workstation 17.5.2 Pro for Windows 更新 OEM BIOS 2.7 支持 Windows Server
    VMwareWorkstation17.5.2ProforWindows更新OEMBIOS2.7支持WindowsServer2025VMwareWorkstation17.5.2PromacOSUnlocker&OEMBIOS2.7forWindows在Windows上运行macOSSonoma请访问原文链接:https://sysin.org/blog/vmware-workstation-17-unlocker-win......
  • 读书笔记:高效C/C++调试
    高效C/C++调试(美)严琦、卢宪廷目录第1章调试符号和调试器11.1调试符号11.1.1调试符号概览2全局变量文件行号数据类型1.1.2DWARF格式31.2实战故事1:数据类型的不一致141.3调试器的内部结构161.3.1用户界面161.3.2符号管理模块161.3.3目标管理模块......