【问题标题】:What exactly is a cancellation point?什么是取消点?
【发布时间】:2015-02-07 02:16:54
【问题描述】:

我试图弄清楚 C++ 中的取消点到底是什么。我已阅读:

man pageWhat are pthread cancellation points used for

但我在某些方面仍然有些困惑。例如,我正在使用文件 write() 函数。显然这是一个取消点。所以当我调用 write() 时,我可以看到另一个线程可能开始处理(所以我的代码从写入线程切换到另一个线程),这通常发生在写入缓冲区已满并且需要在写入之前清空时() 可以成功/完成。

但在我看来,这不是取消线程,而只是暂时的阻塞/挂起,没有线程“清理”可做……

所以我的问题是,取消点是否与“阻塞点”有关? - 它们真的是一回事,还是有一些不同? 任何关于取消点的明确“顶级”描述都会非常有用。

【问题讨论】:

  • 取消点通常是控制流中控制返回调度程序的任何点。 “取消”的唯一可能含义是不再被安排,因此只有在可以影响安排决策的情况下才能取消某些内容。系统调用形成与调度程序的自然交互,尽管可能还有其他调用。
  • @KerrekSB 有了这个评论和 Bogdan V 的回答,我认为这对我来说真的很有意义,谢谢 :)
  • 感谢@KerrekSB 对调度程序的清晰、简洁和可靠的解释。

标签: c++ cancellation


【解决方案1】:

当您的线程退出执行时,其状态由操作系统保存,这并不是线程的取消。取消意味着线程根据请求终止,其特定目的是让所有内容在完成时处于最终状态(也就是释放所有资源,更新所有处理程序等)。

您所说的阻塞可能会在取消中途发生在线程上。

示例:线程收到取消请求。操作系统将其排队,直到线程变为可取消。当线程变为可取消,并且线程正在执行取消点时,可以清理和取消线程。 write 函数是一个取消点,这意味着从操作系统的角度来看,在执行此函数时取消线程是安全的(所有相关资源的状态将是一致的)。

当取消过程正在运行时,线程可以被阻塞多少次,只要操作系统认为合适。

作为附加说明,如果您查看 POSIX 对取消点的要求,几乎所有阻塞接口都必须是取消点。否则,在任何完全阻塞的线程上(在这样的调用中),都没有安全的方法来终止该线程。

http://man7.org/linux/man-pages/man7/pthreads.7.html

【讨论】:

  • 啊,这更有意义。因此,取消点确实是用于取消线程,但是与“阻塞点”有非直接关系,因为正如您所说,否则您可能会遇到甚至无法杀死的“死锁”线程...我认为这回答了我的问题并消除了我的困惑:)
  • 从技术上讲,死锁的线程可以用 pthread_kill 杀死。目标线程将获得 SIGKILL。但是例如,线程本地存储中的对象的析构函数不会被调用。此外,当被杀死时,不能保证用于线程的内部结构将被释放。 pthread_cancel 旨在成为您无法进行联接时“最干净”的方式。
  • @BogdanV.:如果你用 SIGKILL 击中进程中的任何线程,整个进程都会死掉,而不仅仅是线程。它必须以这种方式工作,因为常规的 kill 系统调用已经“随机”选择了一个目标线程,而 pthread_kill 只是让您选择要发出信号的线程。 POSIX explicitly documents this:“请注意,pthread_kill() 只会在给定线程的上下文中处理信号;信号操作(终止或停止)会影响整个进程。”
【解决方案2】:

当您想使用 pthread_cancel() 从另一个线程(例如,从主线程)终止或取消一个线程时,会发生以下情况 (c.f.):

pthread_cancel() 函数向线程thread发送取消请求。

目标线程不会立即终止,而是在它到达取消点时终止(c.f.):

POSIX.1 指定某些函数必须,而某些其他函数必须 功能可能是取消点。如果线程是可取消的, 它的可取消性类型是延迟的,并且取消请求是 线程挂起,然后线程在调用时被取消 作为取消点的函数。

这些作为取消点的函数是否也可能阻塞线程的执行,目前不相关。文档中有这些函数的列表:

请注意,有些设置会影响线程的行为和“可取消性”,为了简单起见,我在此处省略了这些设置。进一步阅读:

【讨论】:

  • 感谢所有链接,我已经阅读了大部分链接,我认为我的困惑的根源是因为我认为“阻塞”点与其他答案清除的取消点相同为我准备。不过,为所有信息 +1 :)
猜你喜欢
  • 2010-09-30
  • 2014-06-06
  • 1970-01-01
  • 1970-01-01
  • 2018-06-09
  • 1970-01-01
  • 2020-04-07
  • 1970-01-01
相关资源
最近更新 更多