다음을 통해 공유


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

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

OpenMP에서 병렬 지역에서 throw되는 예외는 동일한 스레드에 의해 동일한 지역에서 catch되고 처리되어야 합니다. 병렬 영역을 이스케이프하는 예외는 처리되지 않은 예외 처리기에 의해 catch되며 기본적으로 프로세스를 종료합니다.

동시성 런타임에서 동시성::task_group 또는 동시성::structured_task_group 개체와 같은 작업 그룹에 전달하는 작업 함수 본문에 예외를 throw하거나 concurrency::p arallel_for와 같은 병렬 알고리즘에 전달하는 경우 런타임은 해당 예외를 저장하고 태스크 그룹 또는 알고리즘이 완료될 때까지 기다리는 컨텍스트로 마샬링합니다. 작업 그룹의 경우 대기 컨텍스트는 동시성::task_group::wait, 동시성::structured_task_group::wait, 동시성::task_group::run_and_wait 또는 동시성::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에서 동시성 런타임으로 마이그레이션
예외 처리
병렬 알고리즘