首页 > 系统相关 >windows C++-并行编程-转换使用异常处理的 OpenMP 循环以使用并发运行时

windows C++-并行编程-转换使用异常处理的 OpenMP 循环以使用并发运行时

时间:2024-09-07 17:22:02浏览次数:11  
标签:std alloc windows occurred C++ bad error OpenMP 异常

此示例演示如何将执行异常处理的 OpenMP 并行 for 循环转换为使用并发运行时异常处理机制。

在 OpenMP 中,在并行区域中引发的异常必须由同一线程在同一区域中捕获和处理。 未处理的异常处理程序会捕获逃离并行区域的异常,默认情况下会终止进程。

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

示例

此示例演示如何在 OpenMP parallel 区域和对 parallel_for 的调用中处理异常。 do_work 函数执行未成功的内存分配请求,因此引发 std::bad_alloc 类型的异常。 在使用 OpenMP 的版本中,引发异常的线程也必须捕获它。 换句话说,OpenMP 并行循环的每次迭代都必须处理异常。 在使用并发运行时的版本中,主线程捕获另一个线程引发的异常。

// concrt-omp-exceptions.cpp
// compile with: /EHsc /openmp
#include <ppl.h>
#include <new>
#include <iostream>
#include <sstream>

using namespace concurrency;
using namespace std;

// Demonstrates a function that performs a memory allocation request 
// that does not succeed.
void do_work(int)
{
   // The following memory allocation causes this function to 
   // throw std::bad_alloc.
   char* ptr = new char[(~unsigned int((int)0)/2) - 1];

   // TODO: Assuming that the allocation succeeds, perform some work 
   // and free the allocated memory.

   delete[] ptr;
}

// Demonstrates an OpenMP parallel loop that performs exception handling.
void omp_exception_handling()
{
   #pragma omp parallel for 
      for(int i = 0; i < 10; i++) 
      {
         try {
            // Perform a unit of work.
            do_work(i);
         }
         catch (exception const& e) {
            // Print the error to the console.
            wstringstream ss;
            ss << L"An error of type '" << typeid(e).name() 
               << L"' occurred." << endl;
            wcout << ss.str();
         }
      }
}

// Demonstrates an Concurrency Runtime parallel loop that performs exception handling.
void concrt_exception_handling()
{
   try {
      parallel_for(0, 10, [](int i) 
      {
         // Perform a unit of work.
         do_work(i);
      });
   }
   catch (exception const& e) {
      // Print the error to the console.
      wcout << L"An error of type '" << typeid(e).name() 
            << L"' occurred." << endl;
   }
}

int wmain()
{
   wcout << L"Using OpenMP..." << endl;
   omp_exception_handling();

   wcout << L"Using the Concurrency Runtime..." << endl;
   concrt_exception_handling();
}

本示例生成以下输出。 

Using OpenMP...
An error of type 'class std::bad_alloc' occurred.
An error of type 'class std::bad_alloc' occurred.
An error of type 'class std::bad_alloc' occurred.
An error of type 'class std::bad_alloc' occurred.
An error of type 'class std::bad_alloc' occurred.
An error of type 'class std::bad_alloc' occurred.
An error of type 'class std::bad_alloc' occurred.
An error of type 'class std::bad_alloc' occurred.
An error of type 'class std::bad_alloc' occurred.
An error of type 'class std::bad_alloc' occurred.
Using the Concurrency Runtime...
An error of type 'class std::bad_alloc' occurred.

 在使用 OpenMP 的此示例版本中,异常发生在每个循环迭代中并进行处理。 在使用并发运行时的版本中,运行时存储异常,停止所有活动任务,丢弃任何尚未启动的任务,并将异常封送到调用 parallel_for 的上下文中。

如果要求使用 OpenMP 的版本在发生异常后终止,可以使用布尔标记向其他循环迭代发出信号,指出错误的发生。 如主题如何:将使用取消的 OpenMP 循环转换为使用并发运行时中的示例,如果设置了该标记,后续循环迭代将不会执行任何操作。 相反,如果要求使用并发运行时的循环在发生异常后继续,则在并行循环体本身中处理异常。

并发运行时的其他组件,例如异步代理和轻量级任务,不传输异常。 相反,未处理的异常处理程序会捕获未处理的异常,默认情况下会终止进程。

编译代码

复制示例代码,并将它粘贴到 Visual Studio 项目中,或粘贴到名为 concrt-omp-exceptions.cpp 的文件中,再在 Visual Studio 命令提示符窗口中运行以下命令。

cl.exe /EHsc /openmp concrt-omp-exceptions.cpp

标签:std,alloc,windows,occurred,C++,bad,error,OpenMP,异常
From: https://blog.csdn.net/m0_72813396/article/details/141575775

相关文章

  • c++元对象实现
    c++元对象实现在C++中,元对象技术通常指的是运行时检查类型信息和对象信息的能力。C++11标准引入了typetraits和reflection的概念,允许我们在编译时获取和使用类型信息。下面是一个简单的C++类,使用了C++11的typetraits和C++17的std::any来实现元对象:  #include<iostrea......
  • C++ 调用 C# - AOT 方案
    一些C#AOT编译的笔记,整体感觉:简单很方便,但限制也很多,适用于比较单一的功能点。跨语言调用C#代码的新方式-DllExport-InCerry-博客园在.NET8下,直接添加<PublishAot>true</PublishAot>就可以支持了,需要注意一些限制,这里比较相关的是,不能使用Newtonsoft.Json做序列......
  • C++ 调用 C# - DllExport 方案
    3F/DllExport:.NETDllExportwith.NETCoresupport(aka3F/DllExportakaDllExport.bat)目前还不支持.NET6以及后续的版本,看起来作者生活上遇到了一些麻烦,暂时也不打算处理了无法使用.NET6工作·问题#197·3F/DllExport---Unabletogetworkingusing.NET6......
  • C++ 调用 C# - C++/CLI 方案
    C++/CLI方案是通过托管C++做中间层,来转发C#和C++之间的调用和数据传递。这个写法,C#不用做任何特殊的处理,正常写就可以。C++/CLI层新建一个C++/CLI项目,e.g.MedicalDbAccessWrapper,添加对C#项目的引用,注意,输出目录最好就是原生C++项目的输出目录,原生C++项目......
  • Python windows虚拟环境离线安装依赖
    前提需要一台有网的机器下载whl包能够拷贝到离线机器创建虚拟环境安装虚拟环境之前,需要你本地有一套python环境。比如我本地python环境:创建虚拟环境命令:python-mvenvmyvenv创建成功后会生成myvenv目录,并且有Scripts文件夹(这里存放的就是虚拟环境的python解释器,pychr......
  • Qt C++编程 从入门到实践 彭源 清华大学出版社
    第一章程序设计基础1.2.1输入和输出操作iostream叫做标准输入输出流库头文件namespacestd叫做标准命名空间cout、cin叫做标准输出、输入流对象有时候看见std::cout的代码,是因为没有事先声明cout对象是从标准命名空间调用的,::叫做域解析运算符,作用就是指明cout这个对象是......
  • [C++ Daily] 递归锁解决标准锁的典型应用
    递归锁解决标准锁的典型应用先看源码:结果(在A种尝试锁住mutex_时失败,进程等待,死锁无法退出:将std::mutex用std::recursive_mutex替换:结果:解析:std::recursive_mutex允许同一个线程对同一个锁对象进行多次上锁,获得多层所有权.......
  • C++中的字符和字符串
    一:引言1、错误分析请先看一下以下代码#include<iostream>#include<utility>//包含pair和make_pair的定义intmain(){//创建pair对象std::pair<int,std::string>p1(1,"one");//使用make_pair创建pair对象autop2=std::make_pair(2,"t......
  • 迷宫,返回所有路径并排序(C++)(回溯+dfs)
    题意说明:要求给出一个m*n的矩阵迷宫,0代表入口,1代表道路,2代表墙体,3代表出口,要求返回从入口到出口的所有移动路径并按长短从小到大排序。移动路径:就是wasd的移动路径,如一共走三步:下,右,下,则输出:sds。代码如下:#include<iostream>#include<string>#include<vector>#include<alg......
  • 【C++】模板初阶
    【C++】模板初阶1.函数模板(1).函数模板概念(2).函数模板格式(3).函数模板的原理(4).函数模板的实例化2.类模板(1).类模板的定义格式(2).类模板的实例化1.函数模板(1).函数模板概念函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据......