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

R..*_*R.. 10 c c++ posix pthreads cancellation

GNU C库现在使用DWARF2展开来进行pthread取消,这样C++异常和pthread取消清理处理程序都可以通过公共调用框架展开进程调用,该过程在必要时调用自动对象的析构函数.不过,据我所知,仍然没有标准,规定(POSIX)线程和C++之间的相互作用,可能希望可移植的应用程序应当假定抛出异常出取消清理上下文是一样调用未定义longjmp出其中,取消具有非平凡析构函数的实时自动对象的线程也是未定义的行为.

是否有任何标准化过程正在进行中,以解决这种相互作用,或者是否可以预期未来的未定义?C++ 11在其线程支持中是否有任何类似的POSIX线程消除概念?

Nia*_*las 13

作为ISO/IEC SC22(包括WG14(C),WG15(POSIX)和WG21(C++))的人,我可以告诉你,快速答案是否定的,C++异常和线程取消不会相互见到任何时间很快.C11和C++ 11没有提到线程取消,并且在大约十年时间内在下一个主要标准发布之前,并非极不可能认识到它.

更长的答案归结为标准如何运作.基本上,ISO只能标准化每个人都可以达成一致意见,人们不同意线程取消.在每个可取消的系统调用之前必须转储状态的执行线程的整个想法违背了现代软件开发的整个精神.它会导致编译器优化的巨大问题,因为与C++异常抛出不同,线程取消被定义为与调用thread_terminate(self)相同,后者明确排除了执行任何其他操作(甚至取消处理程序在许多实现中都不可靠地调用),以及我不认为线程取消支持者会不同意这是一个糟糕的解决方案.

问题是唯一合适的替代方案是使用异步完成变体重新发布POSIX i/o API.而问题在于,不同的POSIX实现非常不同地认为异步完成.我的意思是,我们甚至不能就内核等待队列的标准达成一致,所以在实现这一目标之前,异步i/o API还有很长的路要走.我有一个建议,为下一个标准T​​C/TR在内核等待队列上进行一些移动,但建议的对象是故意非常简单的.

我们在C11/C++ 11中尝试做的是使线程API始终具有非阻塞版本 - 其中只有一个API无法进行非阻塞,即thread_join()(那里没有thread_timedjoin())我计划在获得奥斯汀工作组批准后亲自提交一份勘误表.在所有其他情况下,人们总是可以构建一些轮询,这些轮询不是有效的,但程序是正确的.

从长远来看,从个人角度来说,我发现有很多理由在C语言中添加异常处理,这与C++的语义相似.你不一定会有对象支持(我实际上也支持将非虚拟对象添加到C中),但你会有堆栈解除lambda函数调用的概念.这将让我们通过正确定义的机制正式化黑客攻击.它还可以让你在编写风时编写展开,使编写容错C更容易,更安全,并让旧C透明地与新C交互.

关于在异常处理中抛出异常,我个人认为我们需要做的事情比总是自动调用terminate()更好.由于展开可能导致新对象的构造,或者实际上任何其他异常抛出源,我个人非常希望在终止进程之前进行所有合理的尝试来展开整个堆栈.

因此,简而言之,期望POSIX线程取消继续被视为未定义,并且从长远来看,它很可能会被弃用以支持更好的东西.

顺便说一句,通常POSIX线程取消在实现之​​间是非常不可移植的,因此任何使用POSIX线程取消的代码都有效地依赖于特定于平台的行为,这与使用非POSIX API相同.如果您希望代码可移植,请不要使用POSIX线程取消.而是使用select()或poll()包括魔术"请立即停止线程"文件描述符.在我自己的C++代码中,我实际上有一个系统API包装宏,它测试这个神奇的文件描述符并抛出一个特殊的C++异常.这可确保所有平台(包括Windows)上的相同行为.