简体   繁体   English

是否有任何关于指定C ++异常和pthread取消的交互的动作?

[英]Is there any movement towards specifying interaction of C++ exceptions and pthread cancellation?

The GNU C library uses DWARF2 unwinding for pthread cancellation these days, so that both C++ exceptions and pthread cancellation cleanup handlers get called through a common call frame unwinding process which invokes destructors for automatic objects as necessary along the way. GNU C库现在使用DWARF2展开来进行pthread取消,这样C ++异常和pthread取消清理处理程序都可以通过公共调用框架展开进程调用,该过程在必要时调用自动对象的析构函数。 However, as far as I can tell there is still no standard that specifies the interaction between (POSIX) threads and C++, and presumably an application wishing to be portable should assume that throwing exceptions out of cancellation cleanup contexts is just as undefined as calling longjmp out of them, and that cancelling a thread that has live automatic objects with non-trivial destructors is also undefined behavior. 但是,据我所知,仍然没有标准指定(POSIX)线程和C ++之间的交互,并且可能希望可移植的应用程序应该假设从取消清除上下文中抛出异常与调用longjmp一样未定义除了它们之外,取消具有非平凡析构函数的实时自动对象的线程也是未定义的行为。

Is there any standardization process in progress that addresses this interaction, or is it something that can be expected to be undefined well into the future? 是否有任何标准化过程正在进行中,以解决这种相互作用,或者是否可以预期未来的未定义? Does C++11 have any analogous notion to POSIX thread cancellation in its thread support? C ++ 11在其线程支持中是否有任何类似的POSIX线程消除概念?

As someone who sits on ISO/IEC SC22 which encompasses WG14 (C), WG15 (POSIX) and WG21 (C++), I can tell you that the quick answer is no, C++ exceptions and thread cancellation are not going to see one another any time soon. 作为ISO / IEC SC22(包括WG14(C),WG15(POSIX)和WG21(C ++))的人,我可以告诉你,快速答案是否定的,C ++异常和线程取消不会相互见到任何时间很快。 C11 and C++11 make no mention of thread cancellation, and are highly if not extremely unlikely to recognise it before the next major standards release in about ten years time. C11和C ++ 11没有提到线程取消,并且在大约十年时间内在下一个主要标准发布之前,并非极不可能认识到它。

The longer answer comes down to how standards work. 更长的答案归结为标准如何运作。 Basically ISO can only standardise what everyone can come to agree upon, and people do not agree when it comes to thread cancellation. 基本上ISO只能标准化每个人都可以达成一致意见,人们不同意线程取消。 The whole idea of a thread of execution having to dump state before every cancellable system call goes against the whole ethos of modern software development. 在每个可取消的系统调用之前必须转储状态的执行线程的整个想法违背了现代软件开发的整个精神。 It causes immense problems for compiler optimisation because unlike C++ exception throws, a thread cancel is defined to be the same as calling thread_terminate(self) which explicitly precludes doing anything additional (and even cancellation handlers aren't reliably called on many implementations), and I don't think that the thread cancellation supporters would disagree it's a bad solution. 它会导致编译器优化的巨大问题,因为与C ++异常抛出不同,线程取消被定义为与调用thread_terminate(self)相同,后者明确排除了执行任何其他操作(甚至取消处理程序在许多实现中都不可靠地调用),以及我不认为线程取消支持者会不同意这是一个糟糕的解决方案。

The problem is that the only proper alternative is to reissue the POSIX i/o API with async completion variants. 问题是唯一合适的替代方案是使用异步完成变体重新发布POSIX i / o API。 And the problem with that is that different POSIX implementations think of async completion very differently. 而问题在于,不同的POSIX实现非常不同地认为异步完成。 I mean, we can't even agree on a standard for kernel wait queues, so until that can be achieved an async i/o API is a long way off. 我的意思是,我们甚至不能就内核等待队列的标准达成一致,所以在实现这一目标之前,异步i / o API还有很长的路要走。 I have a proposal to make some movement on kernel wait queues for the next standards TC/TR, but the proposed object is deliberately extremely simplistic. 我有一个建议,为下一个标准T​​C / TR在内核等待队列上进行一些移动,但建议的对象是故意非常简单的。

What we've tried to do in C11/C++11 is for the threading API to always have non-blocking versions - there is only one API in there which can't be done non-blocking which is thread_join() (there is no thread_timedjoin()) and I plan to personally submit an errata on that after I have Austin Working Group approval. 我们在C11 / C ++ 11中尝试做的是使线程API始终具有非阻塞版本 - 其中只有一个API无法进行非阻塞,即thread_join()(那里没有thread_timedjoin())我计划在获得奥斯汀工作组批准后亲自提交一份勘误表。 In all other cases, one can always construct something which polls which isn't efficient, but is program correct. 在所有其他情况下,人们总是可以构建一些轮询,这些轮询不是有效的,但程序是正确的。

In the longer run, personally speaking I see plenty of good reason to add exception handling to C following similar semantics to C++. 从长远来看,从个人角度来说,我发现有很多理由在C语言中添加异常处理,这与C ++的语义相似。 You wouldn't have object support necessarily (I would actually support adding non-virtual objects to C too personally), but you would have the concept of stack unwound lambda function calls. 你不一定会有对象支持(我实际上也支持将非虚拟对象添加到C中),但你会有堆栈解除lambda函数调用的概念。 That would let us formalise hacks like thread cancellation with a properly defined mechanism. 这将让我们通过正确定义的机制正式化黑客攻击。 It also makes writing fault tolerant C much easier and safer by letting you write the unwind as you write the wind, and lets old C transparently interop with new C. 它还可以让你在编写风时编写展开,使编写容错C更容易,更安全,并让旧C透明地与新C交互。

Regarding throwing exceptions from within exception handling, me personally I think we need to do something better than just always auto invoking terminate(). 关于在异常处理中抛出异常,我个人认为我们需要做的事情比总是自动调用terminate()更好。 As unwinding may cause the construction of new objects, or indeed any other source of exception throws, I personally would greatly prefer if every reasonable attempt is made to unwind the whole stack before terminating the process. 由于展开可能导致新对象的构造,或者实际上任何其他异常抛出源,我个人非常希望在终止进程之前进行所有合理的尝试来展开整个堆栈。

So, in short, expect POSIX thread cancellation to continue to be viewed as undefined, and the strong chances are in the long run it'll get deprecated in favour of something better. 因此,简而言之,期望POSIX线程取消继续被视为未定义,并且从长远来看,它很可能会被弃用以支持更好的东西。

BTW, generally POSIX thread cancellation is highly unportable between implementations, so any code which uses POSIX thread cancellation is effectively relying on platform-specific behaviour which is identical to using non-POSIX APIs. 顺便说一句,通常POSIX线程取消在实现之​​间是非常不可移植的,因此任何使用POSIX线程取消的代码都有效地依赖于特定于平台的行为,这与使用非POSIX API相同。 If you want your code to be portable, don't use POSIX thread cancellation. 如果您希望代码可移植,请不要使用POSIX线程取消。 Instead use select() or poll() including a magic "please stop thread now" file descriptor. 而是使用select()或poll()包括魔术“请立即停止线程”文件描述符。 In my own C++ code, I actually have a system API wrapper macro which tests for this magic file descriptor and throws a special C++ exception. 在我自己的C ++代码中,我实际上有一个系统API包装宏,它测试这个神奇的文件描述符并抛出一个特殊的C ++异常。 This ensures identical behaviour on all platforms, including Windows. 这可确保所有平台(包括Windows)上的相同行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM