POSIX 指定了两种线程取消类型:PTHREAD_CANCEL_ASYNCHRONOUS
, and PTHREAD_CANCEL_DEFERRED
(通过设置pthread_setcanceltype(3)
) 确定何时pthread_cancel(3)
应该生效。根据我的阅读,POSIX 手册页对此没有太多说明,但 Linux 手册页说了以下内容:PTHREAD_CANCEL_ASYNCHRONOUS
:
该线程可以随时取消。 (一般情况下,收到取消请求后会立即取消,但系统不保证这一点。)
我很好奇关于的含义系统不保证这一点。我可以很容易地想象这种情况发生在多核/多 CPU 系统中(在上下文切换之前)。但是单核系统呢:
- 当请求取消并且启用取消时,我们是否可以让线程不立即取消(
pthread_setcancelstate(3)
) 并取消类型设置为PTHREAD_CANCEL_ASYNCHRONOUS
?
- 如果是,在什么条件下会发生这种情况?
我主要对 Linux (LinuxThreads / NPTL) 感到好奇,但更普遍地对查看此取消业务的 POSIX 标准兼容方式感到好奇。
更新/澄清:这里真正的实际问题是调用后立即销毁的资源的使用pthread_cancel()
其中目标线程已启用取消并设置为类型PTHREAD_CANCEL_ASYNCHRONOUS
!!!所以重点是:在这种情况下被取消的线程在上下文切换后是否有很小的可能性继续正常运行(即使是很短的时间)?
感谢达蒙的回答,减少了与下一个上下文切换相关的信号传递和处理的问题。
更新2:我回答了我自己的问题,指出这是一个不好的担忧,底层的程序设计应该在根本不同的概念层面上解决。我希望这个“错误”的问题对于其他想了解异步取消奥秘的人来说是有用的。
其含义正如其所言:不能保证立即发生。其原因是实施细节需要一定的“自由度”,并在标准中予以考虑。
例如在Linux/NPTL下,通过发送信号nr来实现取消。 32. 当接收到信号时,线程被取消,这通常发生在下一次内核到用户的切换时,或者在下一次中断时,或者在时间片结束时(其中may一不小心就会立刻但通常不是)。但是,当线程未运行时,永远不会收到信号。所以这里真正的问题实际上是signals不一定会立即收到。
如果你仔细想想,你甚至不可能做出有多大不同的事情。既然你可以phtread_cleanup_push
操作系统必须执行的一些处理程序(它不能简单地使线程消失!),线程must必然运行被取消。无法保证any特定线程(包括您要取消的线程)在您取消线程的确切时间正在运行,因此不能保证它会立即取消。
当然,假设操作系统的实现方式是阻塞调用线程并调度要取消的线程,以便它执行其处理程序,并且仅在之后解除阻塞 pthread_cancel。但是由于pthread_cancel
没有指定为阻塞,这将是一个非常令人讨厌的惊喜。由于干扰执行时间限制和调度程序公平性,这也有些不可接受。
因此,如果您的取消类型是“禁用”,那么什么也不会发生。或者,它是“enable”,并且取消类型是“deferred”,那么线程在调用被列为取消点的函数时取消pthreads(7)
.
或者,它是“异步”的,那么如上所述,操作系统将在它认为合适的时候做“某事”来取消线程——不是在精确的、明确定义的时间,而是“很快”。对于 Linux,通过发送信号。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)