Ответ 1
Q1
Да, std::terminate
можно вызывать одновременно.
Q2
В стандарте указано, что поведение undefined для terminate_handler
не означает "прекратить выполнение программы, не возвращаясь к вызывающему". В реализациях, с которыми я знаком, если запрос terminate_handler
будет возвращаться, как обычно, так и исключительно, abort()
будет вызван.
Q3
Функция, установленная std::terminate
, является глобальной, а не локальной. Таким образом, один поток может воздействовать на другой.
В С++ 98/03 используется terminate_handler
, когда terminate
вызывается из-за неперехваченного исключения - это тот, который был действителен при вызове исключения, а не тот, который действует, когда terminate
(хотя они, как правило, одинаковы).
В С++ 11 это было изменено, и теперь в стандарте говорится, что используемый обработчик является тем, который находится на месте в момент вызова terminate
. Это изменение было сделано по ошибке и, скорее всего, будет исправлено в будущем проекте. Вот проблема LWG, отслеживающая эту проблему:
http://cplusplus.github.com/LWG/lwg-active.html#2111
Обновление
На совещании Spring 2015 г. в Lenexa, KS LWG решила стандартизировать существующее поведение и сделала его неуказанным, когда новый terminate_handler
вступает в силу, если set_terminate
вызывается во время разворачивания стека. То есть реализациям разрешено следовать либо правилам С++ 98/03, либо правилам С++ 11.
Чтобы сделать ваш код переносимым, если вам нужно установить terminate_handler
, сделайте это во время запуска программы, прежде чем будут выбрасываться какие-либо исключения, и не делайте привычки вызывать set_terminate
после этого.