微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

GNU C库现在使用DWARF2进行pthread取消,以便通过一个通用的调用帧解卷过程来调用C异常和pthread取消清除处理程序,该过程会在必要时调用自动对象的析构函数.然而,据我所知,至今还没有指定(POSIX)线程和C之间的交互的标准,并且假定一个希望可移植的应用程序应该假定抛出异常消除清除上下文与调用longjmp一样未定义并且取消了一个具有非平凡析构函数的实时自动对象的线程也是未定义的行为.

是否有任何正在进行的标准化过程来解决这种互动问题,还是可以预期未来将会有未定义的东西? C11在其线程支持中是否有与POSIX线程取消相似的概念?

解决方法

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

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

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

我们在C11 / C11中尝试做的是线程API始终具有非阻塞版本 – 在那里只有一个API不能执行非阻塞,这是thread_join()(没有thread_timedjoin()),我计划在奥斯丁工作组批准后亲自提交勘误表.在所有其他情况下,总是可以构建一些不是有效的投票,但程序是正确的.

从长远来看,个人来说,我看到很多很好的理由,将类似于C语义的语义添加到C中.您不会有对象支持(我实际上将支持将非虚拟对象添加到C中),但是您可以使用堆栈解开lambda函数调用的概念.这将让我们用正确定义的机制来形式化线程消除.它也使写作容错C更容易和更安全,让你在写风时写出放松,让老C透明地与新的C.

关于从异常处理中抛出异常,我个人认为我们需要做的更好,而不是总是自动调用terminate().由于放松可能会导致新物体的构造,或者其他任何其他异常来源的抛出,我个人会非常希望在终止该过程之前,每次合理尝试展开堆叠.

所以简单来说,期望POSIX线程取消继续被看作是未定义的,而且从长远来看,强大的机会将会被弃用,更好地利用这一点.

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

原文地址:https://www.jb51.cc/c/115874.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐