是否有任何正在进行的标准化过程来解决这种互动问题,还是可以预期未来将会有未定义的东西? C11在其线程支持中是否有与POSIX线程取消相似的概念?
解决方法
更长的答案归结于标准的工作原理.基本上,ISO只能规范每个人都可以达成一致,人们不同意线程取消.在每次可取消的系统调用之前,执行线程的所有想法必须转储状态都违背了现代软件开发的整个精神.它导致编译器优化的巨大问题,因为与C异常抛出不同,线程取消被定义为与调用thread_terminate(self)相同,这显然排除了执行任何额外的(甚至在许多实现中不可靠地调用取消处理程序),以及我不认为线程取消支持者不同意这是一个坏的解决方案.
问题是唯一合适的替代方法是使用异步完成变体重新发布POSIX i / o API.而且问题在于不同的POSIX实现会非常不同地认为异步完成.我的意思是,我们甚至不能同意内核等待队列的标准,所以直到可以实现异步i / o API是一个很长的路要走.我有一个建议,对于下一个标准TC / 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)上的相同行为.