G ++ предполагает, что исключения могут создаваться только при вызовах функций. Если вы собираетесь нарушить это предположение (например, выбрасывая их из обработчиков сигналов), вам нужно передать -fnon-call-exceptions
в G ++ при сборке вашей программы.
Обратите внимание, однако, что это заставляет G ++:
Generate code that allows trapping instructions to throw
exceptions. Note that this requires platform-specific runtime
support that does not exist everywhere. Moreover, it only allows
_trapping_ instructions to throw exceptions, i.e. memory
references or floating point instructions. It does not allow
exceptions to be thrown from arbitrary signal handlers such as
`SIGALRM'.
Это означает, что исключение из середины некоторого случайного кода НИКОГДА не безопасно. Вы можете только исключить из SIGSEGV
, SIGBUS
и SIGFPE
, и только если вы передаете -fnon-call-exceptions
, и они были вызваны из-за ошибки в работающем коде. Единственная причина, по которой это сработало в потоке 1, заключается в том, что из-за существования вызова usleep()
G ++ был вынужден предположить, что он может выдать. В потоке 2 G ++ видит, что команды перехвата не было, и устраняет блок try-catch.
Вы можете найти поддержку отмены pthread более похожей на то, что вам нужно, или просто добавить где-нибудь такой тест:
if (*(volatile int *)terminate_flag) throw terminate_exception();