Not
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Det här exemplet visar hur du konverterar en OpenMP-parallellför loop som utför undantagshantering till att använda undantagshanteringsmekanismen i Concurrency Runtime.
I OpenMP måste ett undantag som genereras i en parallell region fångas upp och hanteras i samma region av samma tråd. Ett undantag som undflyr den parallella regionen fångas av den ohanterade undantagshanteraren, vilket avslutar processen som standard.
När du i Concurrency Runtime genererar ett undantag i brödtexten för en arbetsfunktion som du skickar till en aktivitetsgrupp, till exempel en concurrency::task_group eller concurrency::structured_task_group objekt, eller till en parallell algoritm som concurrency::parallel_for, lagrar körningen undantaget och överför det till konteksten som väntar på att aktivitetsgruppen eller algoritmen ska slutföras. För aktivitetsgrupper är den väntande kontexten den kontext som anropar concurrency::task_group::wait, concurrency::structured_task_group::wait, concurrency::task_group::run_and_wait eller concurrency::structured_task_group::run_and_wait. För en parallell algoritm är väntekontexten den kontext som anropade den algoritmen. Körningstiden stoppar även alla aktiva uppgifter som finns i uppgiftsgruppen, inklusive de i underordnade uppgiftsgrupper, och ignorerar alla uppgifter som ännu inte har startats.
Exempel
Det här exemplet visar hur du hanterar undantag i en OpenMP-region parallel och i ett anrop till parallel_for. Funktionen do_work utför en minnesallokeringsbegäran som inte lyckas och genererar därför ett undantag av typen std::bad_alloc. I den version som använder OpenMP måste tråden som genererar undantaget också fånga den. Med andra ord måste varje iteration av en Parallell OpenMP-loop hantera undantaget. I den version som använder Concurrency Runtime fångar huvudtråden ett undantag som genereras av en annan tråd.
// 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();
}
Det här exemplet genererar följande utdata.
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.
I den version av det här exemplet som använder OpenMP sker undantaget i och hanteras av varje loop-iteration. I den version som använder Concurrency Runtime lagrar körningen undantaget, stoppar alla aktiva aktiviteter, tar bort alla aktiviteter som ännu inte har startats och konverterar undantaget till kontexten som anropar parallel_for.
Om du kräver att den version som använder OpenMP avslutas när undantaget inträffar kan du använda en boolesk flagga för att signalera till andra loop-iterationer om att felet inträffade. Som i exemplet i avsnittet How to: Convert an OpenMP Loop that Uses Cancellation to Use the Concurrency Runtime (Konvertera en OpenMP-loop som använder Annullering för att använda samtidighetskörning) skulle efterföljande loop-iterationer inte göra någonting om flaggan har angetts. Om du däremot kräver att loopen som använder Concurrency Runtime fortsätter efter att undantaget inträffar hanterar du undantaget i själva den parallella loopkroppen.
Andra komponenter i Concurrency Runtime, till exempel asynkrona agenter och lätta uppgifter, transporterar inte undantag. I stället fångas ohanterade undantag av den ohanterade undantagshanteraren, vilket som standard avslutar processen. Mer information om undantagshantering finns i Undantagshantering.
Mer information om parallel_for och andra parallella algoritmer finns i Parallella algoritmer.
Kompilera koden
Kopiera exempelkoden och klistra in den i ett Visual Studio-projekt, eller klistra in den i en fil med namnet concrt-omp-exceptions.cpp och kör sedan följande kommando i ett Visual Studio-kommandotolkfönster.
cl.exe /EHsc /openmp concrt-omp-exceptions.cpp
Se även
Migrera från OpenMP till Concurrency Runtime
undantagshantering
Parallella algoritmer