Передача исключений между потоками
Visual C++ поддерживается передача исключение от одного потока к другому.Передача исключений позволяет перехватывать исключения в одном потоке, а затем выполнить исключение показаться, что было возникает в другой поток.Например, эту функцию можно использовать для создания многопоточного приложения, где основной поток обрабатывает все исключения, вызываемые его вторичными потоками.Передача исключений в основном полезно для разработчиков, которые создают параллельных библиотеки или системы программирования.Для реализации передачи исключения, Visual C++ предоставляет exception_ptr тип и current_exception" rethrow_exceptionи copy_exception функции.
namespace std
{
typedef unspecified exception_ptr;
exception_ptr current_exception();
void rethrow_exception(exception_ptr p);
template<class E>
exception_ptr copy_exception(E e);
}
Параметры
Параметр |
Описание |
---|---|
unspecified |
Неуказанный внутренний класс, используемый для реализации exception_ptr этот тип. |
p |
exception_ptr объект, который ссылается на исключение. |
E |
Класс, представляющий исключение. |
e |
Экземпляр параметра E класс. |
Возвращаемое значение
current_exception функция возвращает exception_ptr объект, который ссылается на исключение, которое в данный момент.Если исключение не выполняется, то функция возвращает exception_ptr объект, который не связан с одним исключением.
copy_exception функция возвращает exception_ptr объект, который ссылается на определенное исключение e параметр.
Заметки
Сценарий
Предположим, что нужно создать приложение, которое может масштабироваться для обработки переменного объема работы.Для достижения этой цели создании многопоточного приложения, где initial, основной поток создает столько вторичных потоков по мере того, как для этого требуется выполнить задание.Вторичные потоки позволяют основной поток для управления ресурсами, распределения нагрузки, а повысить пропускную способность.Можно распределять многопоточное приложение выполняет рабочий, лучше, чем единый-продетое потоков приложения.
Однако если вторичный поток вызывает исключение, то требуется основной поток.Это происходит потому, что требуется приложению обрабатывать исключения в согласованном, унифицированном способом независимо от числа вторичных потоков.
Решение
Для обработки предыдущий сценарий, стандарт C++ поддерживает передачи исключение между потоками.Если вторичный поток вызывает исключение, то исключение будет текущее исключение.По аналогии к реальному миром, говорят, что текущее исключение в полете.Текущее исключение в полете от времени не создается до обработчика исключений, catch он возвращает.
Вторичный поток может перехватить текущее исключение в выражении catch блок, а затем вызывает current_exception функция для хранения исключение в exception_ptr объект.exception_ptr объект должен быть доступны для вторичный поток и в основной поток.Например, exception_ptr объект может быть глобальной переменной к которой управляется мьютексом.Термин исключение транспорта означает, что исключение в одном потоке может быть преобразован в форме, которая может быть доступна другим потоком.
Затем главный поток вызывает метод rethrow_exception функция, которая извлекает а затем выдает исключение из exception_ptr объект.При возникновении исключения является текущим исключением в основном потоке.Иными словами, возникает исключение в основном потоке.
Наконец, основной поток может перехватить текущее исключение в выражении catch отключите и затем процесс его или ее к обработчику исключений создавайте более высокого уровня.Или, основной поток может игнорировать исключение и включение процесс в конец.
Большинство приложений не должны передаваться исключения между потоками.Однако эта функция полезна в параллельной компьютерной системе, поскольку система может разделить работу из вторичных потоков, процессоров или ядер.В такой среде parallel computing, один выделенный поток может обрабатывать все исключения из вторичных потоков и может представлять собой последовательную модель обработки исключений к любому приложению.
Дополнительные сведения о предложении Комитета по стандартам C++, под названием Интернет для номера документа N2179 "поддержкой языка для передачи исключений между потоками".
Модели и параметры компилятора обработки ошибок
Модель обработки исключений приложения, указывающее, является ли она может перехватить исключение и передачи.Visual C++ 3 поддерживает модели, могут обрабатывать исключения C++, структурированные исключения обработки исключений (SEH) и исключения среды CLR.Используйте /EH и /clr параметры компилятора определить модель обработки исключений приложения.
Только следующие параметры компилятора сочетание и выписки программирования могут передавать исключение.Другие сочетания или не могут перехватывать исключения или перехватить, но не могут передаваться исключения.
/EHa и параметр компилятора catchоператор может передать ЕЕ и исключений C++.
/EHa" /EHsи /EHsc параметры компилятора и catchоператор может передачи исключений C++.
/CLR OR /CLR:pure и параметр компилятора catchоператор может передачи исключений C++./CLR параметры компилятора подразумевают спецификацию /EHa параметр.Обратите внимание, что компилятор не поддерживает передачи управляемые исключения.Это происходит потому, что управляемые исключения, которые являются производными от System.Exception класс, уже объекты, которые можно перемещать между потоками с помощью помещений общей среды выполнения languange.
Примечание по безопасности
Рекомендуется указать /EHsc исключения параметра компилятора только C++ и catch.Доступ к которому предоставляется угрозе безопасности при использовании /EHa OR /CLR параметр компилятора и a catch выписка с многоточием исключение-объявление (catch(...)).Возможно, планируется использовать catch выписка для получения некоторых конкретных исключений.Однако catch(...) выписка перенаправляет все C++ и исключений, включая непредвиденные один, которые должны быть смертоносны.Если игнорируете или mishandle непредвиденное исключение, то вредоносный код может использовать эту возможность заминировать безопасность программы.
Использование
В следующих разделах описываются способы передачи исключения с помощью exception_ptrтип и current_exception" rethrow_exceptionи copy_exception функции.
тип exception_ptr
Используйте exception_ptr объект для ссылки на текущее исключение или экземпляр пользователь-определенного исключения.В реализации Майкрософт, представленное исключение EXCEPTION_RECORD структура.Каждое exception_ptr объект включает эталонное поле исключения, указывающий на копии EXCEPTION_RECORD структура, представляющая исключение.
При объявлении exception_ptr переменная, переменная не связанную с исключением.То есть, его эталонное поле исключения значение null.Такое exception_ptr объект вызывается a null exception_ptr.
Используйте current_exception OR copy_exception функция для присвоения исключение exception_ptr объект.При присвоении исключение exception_ptr переменная указывает эталонного поля разрешение ей копии исключения.Если недостаточно памяти для копирования исключение, то точки эталонного полей исключения из копии a std:: bad_alloc исключение.Если current_exception OR copy_exception функция не может копировать исключение по какой-либо другой причине, вызовов функций terminate (CRT) функция, чтобы выйти из текущего процесса.
Несмотря на свое имя exception_ptr сам объект не является указателем.Он не повинуется семантике указателя и не может быть использован с доступом (элемента указателя->косвенного обращения) или операторы (*).exception_ptr объект не имеет открытые элементы данных или функции-члены.
Сравнения:
Можно использовать равно (==и не-равно ()!=) операторы для сравнения 2 exception_ptr объекты.Операторы сравнения значений не binary (битовый шаблон) EXCEPTION_RECORD структуры, представляющие исключения.Вместо этого операторы сравнивают адреса в эталонном поле исключения exception_ptr объекты.Поэтому null exception_ptr сравнивает и значения Null как равные.
функция current_exception
Вызовите current_exception функция a catch блок.Если в полете и исключение catch блок может перехватить исключение current_exception функция возвращает exception_ptr объект, который ссылается на исключение.В противном случае эта функция возвращает значение null exception_ptr объект.
Сведения:
current_exception функция перенаправляет исключение, в полете независимо от наличия catch определяет оператор исключение-объявление выписка.
Деструктор вызывается в конце текущего исключения catch блок если это не было сделано rethrow исключение.Однако даже если вызватьcurrent_exception в деструкторе, функцияфункция возвращает exception_ptr объект, который ссылается на текущее исключение.
Последовательные вызовы current_exception return функций exception_ptr объекты, которые ссылаются на разные копиям текущего исключения.Следовательно, объекты сравниваются по мере не равны, поскольку они ссылаются на разные копиям, даже если копии имеют одинаковое значение binary.
ОНА исключения:
При использовании /EHa параметр компилятора, ЕГО можно перехватить исключение в C++ catch блок.current_exception функция возвращает exception_ptr объект, который ссылается на ЭТО исключение.и rethrow_exception функция создаст ЕЕ исключение при вызове его странспортировано exception_ptr объект в качестве аргумента.
current_exception функция возвращает значение null exception_ptr при вызове его в НЕГО __finally обработчик завершения, __except обработчик исключений или __except критерий фильтра.
Транспортированное исключение не поддерживает вложенные исключения.Вложенное исключение возникает, если другое исключение, если исключение обработано.Если перехватывать вложенного исключения EXCEPTION_RECORD.ExceptionRecord элемент данных в цепочке EXCEPTION_RECORD структуры, описывающие связанные исключения.current_exception функция не поддерживает вложенные исключения, поскольку она возвращает exception_ptr объект которого ExceptionRecord элемент данных обнуленн.
Если перехватывать исключение, ЕЕ необходимо управление памятью, на которую ссылается указатель в любой EXCEPTION_RECORD.ExceptionInformation массив элементов данных.Необходимо гарантировать, что память является допустимой во время существования соответствовать exception_ptr объект, и что память освобождается после exception_ptr объект удаляется.
Можно использовать функции переводчика структурированные исключения (SE) вместе с функцией исключений транспорта.Если исключение переведена на C++, то исключение current_exception функция возвращает exception_ptr он ссылается на переведенное исключение вместо оригинала ЭТО исключение.rethrow_exception функция затем вызывает переведенное исключение, не исходное исключение.Дополнительные сведения о функциях см. в разделе переводчика SE _set_se_translator.
функция rethrow_exception
После того как обнаружено исключение при сохранении exception_ptr объект, основной поток может обрабатывать объект.В основном потоке, вызовите rethrow_exception функция вместе с exception_ptr объект в качестве аргумента.rethrow_exception функция извлекает из исключение exception_ptr объект, после чего вызывает исключение в контексте основного потока.Если p параметр rethrow_exception функция null exception_ptrфункция вызывает std:: bad_exception.
Извлеченный исключение теперь текущее исключение в основном потоке, и его можно изменить так же как и любое другое исключение.Если перехватывать исключение, то можно обработать его немедленно или использовать a throw выписка отправлять ее к обработчику исключений более высокого уровня.В противном случае ничего не делать и воспрепятствуйте по умолчанию обработчик исключений системы завершить этот процесс.
функция copy_exception
copy_exception функция принимает экземпляр класса в качестве аргумента его и затем возвращается exception_ptr он ссылается на экземпляр.Обычно указывается класс исключения объект в качестве аргумента copy_exception функция, хотя какой-либо объект класса может быть аргументом.
Вызов copy_exception функция эквивалентна создания исключения с++, улавливая ее в a catch блок, а затем вызвать current_exception функция для возврата exception_ptr объект, который ссылается на исключение.Реализация Майкрософт copy_exception функция является более эффективным, чем вызов, а затем улавливающ исключение.
Приложения обычно не требует copy_exception функция и мы обескураживаем его использование.
Пример
В следующем примере передает стандартное исключение C++ и пользовательские исключения C++ из одного потока к другому.
// transport_exception.cpp
// compile with: /EHsc /MD
#include <windows.h>
#include <stdio.h>
#include <exception>
#include <stdexcept>
using namespace std;
// Define thread-specific information.
#define THREADCOUNT 2
exception_ptr aException[THREADCOUNT];
int aArg[THREADCOUNT];
DWORD WINAPI ThrowExceptions( LPVOID );
// Specify a user-defined, custom exception.
// As a best practice, derive your exception
// directly or indirectly from std::exception.
class myException : public std::exception {
};
int main()
{
HANDLE aThread[THREADCOUNT];
DWORD ThreadID;
// Create secondary threads.
for( int i=0; i < THREADCOUNT; i++ )
{
aArg[i] = i;
aThread[i] = CreateThread(
NULL, // Default security attributes.
0, // Default stack size.
(LPTHREAD_START_ROUTINE) ThrowExceptions,
(LPVOID) &aArg[i], // Thread function argument.
0, // Default creation flags.
&ThreadID); // Receives thread identifier.
if( aThread[i] == NULL )
{
printf("CreateThread error: %d\n", GetLastError());
return -1;
}
}
// Wait for all threads to terminate.
WaitForMultipleObjects(THREADCOUNT, aThread, TRUE, INFINITE);
// Close thread handles.
for( int i=0; i < THREADCOUNT; i++ ) {
CloseHandle(aThread[i]);
}
// Rethrow and catch the transported exceptions.
for ( int i = 0; i < THREADCOUNT; i++ ) {
try {
if (aException[i] == NULL) {
printf("exception_ptr %d: No exception was transported.\n", i);
}
else {
rethrow_exception( aException[i] );
}
}
catch( const invalid_argument & ) {
printf("exception_ptr %d: Caught an invalid_argument exception.\n", i);
}
catch( const myException & ) {
printf("exception_ptr %d: Caught a myException exception.\n", i);
}
}
}
// Each thread throws an exception depending on its thread
// function argument, and then ends.
DWORD WINAPI ThrowExceptions( LPVOID lpParam )
{
int x = *((int*)lpParam);
if (x == 0) {
try {
// Standard C++ exception.
// This example explicitly throws invalid_argument exception.
// In practice, your application performs an operation that
// implicitly throws an exception.
throw invalid_argument("A C++ exception.");
}
catch ( const invalid_argument & ) {
aException[x] = current_exception();
}
}
else {
// User-defined exception.
aException[x] = copy_exception( myException() );
}
return TRUE;
}
Требования
заголовок:<исключение>
См. также
Ссылки
структура EXCEPTION_RECORD
синтаксис обработчика