Note
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier les répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de changer de répertoire.
Cet exemple montre comment convertir une boucle parallèle OpenMP qui effectue la gestion des exceptions pour utiliser le mécanisme de gestion des exceptions du runtime de concurrence.
Dans OpenMP, une exception levée dans une région parallèle doit être interceptée et gérée dans la même région par le même thread. Une exception qui échappe à la région parallèle est interceptée par le gestionnaire d’exceptions non gérées, qui termine le processus par défaut.
Dans le runtime de concurrence, lorsque vous lancez une exception dans le corps d’une fonction de travail que vous transmettez à un groupe de tâches tel qu’un objet concurrency::task_group ou concurrency::structured_task_group, ou à un algorithme parallèle tel que concurrency::parallel_for, le runtime stocke cette exception et la marshaling vers le contexte qui attend la fin du groupe de tâches ou de l’algorithme. Pour les groupes de tâches, le contexte d’attente est le contexte qui appelle concurrency::task_group::wait, concurrency::structured_task_group::wait, concurrency::task_group::run_and_wait ou concurrency::structured_task_group::run_and_wait. Pour un algorithme parallèle, le contexte d’attente est le contexte qui a appelé cet algorithme Le runtime arrête également toutes les tâches actives qui se trouvent dans le groupe de tâches, y compris celles des groupes de tâches enfants, et ignore toutes les tâches qui n’ont pas encore démarré.
Exemple
Cet exemple montre comment gérer les exceptions dans une région OpenMP parallel et dans un appel à parallel_for. La fonction do_work effectue une requête d’allocation de mémoire qui échoue et lève donc une exception de type std::bad_alloc. Dans la version qui utilise OpenMP, le thread qui lève l’exception doit également la capturer. En d’autres termes, chaque itération d’une boucle parallèle OpenMP doit gérer l’exception. Dans la version qui utilise le runtime de concurrence, le thread principal capture une exception levée par un autre thread.
// 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();
}
Cet exemple produit la sortie suivante.
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.
Dans la version de cet exemple qui utilise OpenMP, l’exception se produit dans chaque itération de la boucle et est gérée par celle-ci. Dans la version qui utilise le runtime de concurrence, le runtime stocke l’exception, arrête toutes les tâches actives, ignore toutes les tâches qui n’ont pas encore démarré et effectue le marshaling de l’exception vers le contexte qui appelle parallel_for.
Si vous souhaitez que la version qui utilise OpenMP se termine après l’exception, vous pouvez utiliser un indicateur booléen pour signaler aux autres itérations de la boucle que l’erreur s’est produite. Comme dans l’exemple de la rubrique Comment : Convertir une boucle OpenMP qui utilise l’annulation pour utiliser le runtime de concurrence, les itérations suivantes de la boucle ne feraient rien si l’indicateur est défini. À l’inverse, si vous souhaitez que la boucle qui utilise le runtime de concurrence se poursuive après l’exception, gérez l’exception dans le corps de la boucle parallèle lui-même.
Les autres composants du runtime de concurrence, tels que les agents asynchrones et les tâches légères, ne transportent pas les exceptions. Au lieu de cela, les exceptions non gérées sont interceptées par le gestionnaire d’exceptions non gérées, qui termine le processus par défaut. Pour plus d’informations sur la gestion des exceptions, consultez Gestion des exceptions.
Pour plus d’informations sur parallel_for et d’autres algorithmes parallèles, consultez Algorithmes parallèles.
Compilation du code
Copiez le code d’exemple et collez-le dans un projet Visual Studio, ou collez-le dans un fichier nommé concrt-omp-exceptions.cpp, puis exécutez la commande suivante dans une fenêtre d’invite de commandes Visual Studio.
cl.exe /EHsc /openmp concrt-omp-exceptions.cpp
Voir aussi
Migration d’OpenMP vers Concurrency Runtime
Gestion des exceptions
Algorithmes parallèles