应该 set_terminate
/get_terminate
在C ++ 2011或C ++ 2003中为多个线程设置不同的终止异常处理器?
例如。如果我有程序并设置终止处理程序 func_1
;然后我开始3个线程。什么是新线程中的终止处理程序?如果在每个线程中我将设置终止处理程序 func_2
在第一个帖子中, func_3
在第二个线程中等等。
N3242 (C ++ 2011草案)对此一无所知 [handler.functions]
或者在 [support.exception]
/[exception.terminate]
PS:对于这些标准的任何流行实现,您可以回答C ++ 2011或C ++ 2003
PPS:有FCD评论... C ++ FCD评论状态Rev. 5 N3249(2011):
GB 71 18.6.2.4 / 18.8.2.2 / 18.8.3.2
线程的安全性 std::set_new_handler()
, std::set_unexpected()
, std::set_terminate()
,未指定,使得函数无法以线程安全的方式使用。
必须指定函数的线程安全保证,并且应提供新接口,以便以线程安全的方式查询和安装处理程序。
LWG 1365 接受修改
见纸 N3189
17.6.4.7p4说:
打电话给 set_*
和 get_*
功能不得招致数据竞争。打电话到任何一个 set_*
函数应与后续调用同步 set_*
功能和相应的 get_*
功能。
这强烈暗示了 set_*
和 get_*
即使从不同的线程调用,函数也在相同的全局状态下运行。 18.8.3下的所有段落都讨论了“当前的处理函数“,没有提到线程;这表明处理函数是整个程序的属性;类似地,17.6.4.7具有:
2 - C ++程序可能在执行期间安装不同的处理函数[...]
3 - C ++程序可以通过调用以下函数来获取指向当前处理函数的指针[...]
这些段落讨论 当前的处理函数 在程序的上下文中,表明它是程序范围而不是线程本地的。
在标准中它说
18.8.3.2 set_terminate [set.terminate]
terminate_handler set_terminate(terminate_handler f) noexcept;
1效果:将f指定的函数建立为当前处理函数 终止 异常处理。
[[noreturn]] void terminate() noexcept;
2效果:调用当前的terminate_handler函数。 [注意:默认的terminate_handler是 总是考虑 这个上下文中的可调用处理程序。 - 尾注]
你可以看到 terminate()
打电话给 当前 终止处理程序,在 set_handler
它非常明确地说它用于 终止 一个过程。当所有其他异常处理都失败时,无论从哪个线程运行,都会调用此方法。
只有一个终止处理程序,它总是从程序终止的任何地方调用。
C2003没有线程,任何线程支持都是供应商扩展,因此只有供应商提供的文档才有答案。如果处理程序是每个线程,文档应该说。我知道没有实现它。
C ++ 2011没有提到终止处理程序的每线程性质。每个线程维护它是没有意义的,因为你不能在C ++ 11中杀死一个线程。并且有充分的理由(google kill + thread + c ++ 11)。所以无论你做什么,程序都必须终止。看起来有不同的方法来终止程序,具体取决于请求它的线程不是任何人需要的功能。
该标准没有明确规定; [set.terminate] 只有国家
[...]当前处理程序函数,用于终止异常处理。
但是没有提到“当前”是全局还是每个线程。所以这取决于实施。
例如,在MSVC ++中:
https://msdn.microsoft.com/en-us/library/t6fk7h29.aspx
在多线程环境中,为每个线程单独维护终止函数。每个新线程都需要安装自己的终止函数。因此,每个线程负责其自己的终止处理。