방법: 동시성 런타임을 사용하기 위해 예외 처리를 사용하는 OpenMP 루프 변환

이 예제에서는 동시성 런타임 예외 처리 메커니즘을 사용하도록 예외 처리를 수행하는 OpenMP parallelfor 루프를 변환하는 방법을 보여 줍니다.

OpenMP에서 병렬 영역에 throw되는 예외는 동일한 스레드에 의해 동일한 영역에서 catch 및 처리되어야 합니다.병렬 영역을 벗어나는 예외는 처리되지 않은 예외 처리기에 의해 catch되어 기본적으로 프로세스가 종료됩니다.

동시성 같은 작업 그룹에 전달 하는 작업 함수 본문에서 예외가 throw 되 면 런타임에서 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 형식의 예외를 throw합니다.OpenMP를 사용하는 버전에서 예외를 throw하는 스레드는 예외를 catch도 해야 합니다.즉, OpenMP 병렬 루프의 각 반복에서 예외를 처리해야 합니다.동시성 런타임을 사용하는 버전에서 기본 스레드는 다른 스레드에서 throw되는 예외를 catch해야 합니다.

// 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 루프 변환 항목의 예제에서와 같이 플래그가 설정되어 있는 경우 후속 루프 반복은 아무 작업도 수행하지 않습니다.반대로, 예외가 발생한 후 동시성 런타임을 사용하는 루프가 계속되어야 하는 경우 병렬 루프 본문 자체에서 예외를 처리합니다.

동시성 런타임의 기타 구성 요소(예: 비동기 에이전트 및 간단한 작업)에서는 예외를 전송하지 않습니다.대신 처리되지 않은 예외가 처리되지 않은 예외 처리기에 의해 catch되어 기본적으로 프로세스가 종료됩니다.예외 처리에 대한 자세한 내용은 동시성 런타임에서 예외 처리를 참조하십시오.

parallel_for 및 기타 병렬 알고리즘에 대한 자세한 내용은 병렬 알고리즘을 참조하십시오.

코드 컴파일

예제 코드를 복사 하 고 Visual Studio 프로젝트에 붙여 또는 라는 파일에 붙여 concrt-omp-exceptions.cpp 및 다음 Visual Studio 명령 프롬프트 창에서 다음 명령을 실행 합니다.

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

참고 항목

개념

OpenMP에서 동시성 런타임으로 마이그레이션

동시성 런타임에서 예외 처리

병렬 알고리즘