首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >什么时候POSIX线程取消不是立即的?

什么时候POSIX线程取消不是立即的?
EN

Stack Overflow用户
提问于 2013-07-18 09:44:14
回答 2查看 1.5K关注 0票数 3

POSIX为线程取消类型指定了两种类型:PTHREAD_CANCEL_ASYNCHRONOUSPTHREAD_CANCEL_DEFERRED (由pthread_setcanceltype(3)设置),以确定pthread_cancel(3)何时生效。通过我的阅读,POSIX手册页并没有提到这些,但是Linux手册页提供了关于PTHREAD_CANCEL_ASYNCHRONOUS的以下内容

线程可以随时取消。(通常,它将在收到取消请求后立即取消,但系统不能保证这一点。)

我很好奇这个系统的意义并不能保证这一点。我可以很容易地想象这种情况发生在多核/多CPU系统中(在上下文切换之前)。但是单核心系统呢?

  1. 当请求取消并启用取消(pthread_setcancelstate(3))并将取消类型设置为PTHREAD_CANCEL_ASYNCHRONOUS时,是否可以立即取消线程?
  2. 如果是,在什么情况下会发生这种情况?

我主要对Linux (LinuxThreads / NPTL)感兴趣,但也对POSIX标准兼容的查看这种取消业务的方式有更广泛的兴趣。

Update/Clarification:在这里真正实际关注的是在调用pthread_cancel()之后立即销毁的资源的使用,其中目标线程已启用取消并设置为键入PTHREAD_CANCEL_ASYNCHRONOUS!所以关键是:在这种情况下,被取消的线程是否在上下文切换之后(即使在很短的时间内)能够继续正常运行?

感谢Damon的回答,这个问题减少了与下一个上下文切换有关的信号传递和处理。

更新-2:-我回答了我自己的问题,指出这是一个糟糕的问题,底层的程序设计应该在根本不同的概念级别上处理。我希望这个“错误”的问题是有用的,其他人想知道异步取消的奥秘。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-07-18 10:37:30

它的意思就是:它不能保证马上就会发生。这样做的原因是,在执行细节方面需要某种“自由”,并在标准中加以说明。

例如,在Linux/NPTL环境下,通过发送信号nr来实现取消。32.当接收到信号时,线程被取消,这通常发生在下一个内核到用户的交换机,或者在下一个中断,或者在时间片的末尾(这可能是偶然的,但通常不是)。然而,当线程不运行时,从不会接收到信号。所以真正的问题是,信号不一定会立即接收到。

如果你想一想,它甚至不可能做到很大的不同,也。由于您可以phtread_cleanup_push操作系统必须执行的某些处理程序(它不能仅仅爆炸线程的存在!),所以线程必须运行才能取消。无法保证任何特定线程(包括要取消的线程)在取消线程的确切时间运行,因此无法保证它立即被取消。

当然,假设的情况是,如果操作系统是以阻塞调用线程的方式实现的,并对将要取消的线程进行调度,那么它就会执行它的处理程序,然后只会卸载pthread_cancel。但是由于pthread_cancel没有被指定为阻塞,这将是一个非常令人讨厌的惊喜。由于干扰了wtih执行时间限制和调度程序的公平性,这在某种程度上是不可接受的。

所以,无论您的取消类型是“禁用”,那么什么都不会发生。或者,它是“启用”,而取消类型是“延迟”,然后线程在调用pthreads(7)中列出的取消点的函数时取消。

或者,它是“异步的”,然后如上所述,操作系统会在它认为合适的时候做一些“事情”来取消线程--不是在一个精确的、定义明确的时间,而是“很快”。在Linux的情况下,通过发送信号。

票数 8
EN

Stack Overflow用户

发布于 2013-07-27 05:00:53

如果您想知道异步取消何时发生,那么您正在做一些非常错误的事情。

  1. 遵循的标准:--通过故意创建或允许代码存在--它的正确性取决于对平台的假设(单一核心,特定实现,任何东西)--在脚下吃东西。如果可能的话,遵循这些标准几乎总是更好(并在不可能的情况下清楚地记录下来)。名称PTHREAD_CANCEL_ASYNCHROUNOUS本身表示异步的含义,它不同于直接的甚至几乎是即时的。最初的海报明确规定了单个核心,但是为什么要允许代码以非确定性的方式存在,当您的代码在真正的并行机器(多核或CPU)中运行时,实际上不可能保证立即性(这需要阻止其他内核运行或等待上下文切换或其他一些操作系统/CPU不支持支持您的非常规愿望的可怕攻击)。异步线程取消模式并不意味着保证立即取消线程。因此,以这种方式使用它们是一种非常令人费解的攻击,即使它能够工作。
  2. Async-Safeness:如果您关注异步取消机制,就会产生这样的怀疑:所讨论的线程(由于缺乏独立性)可能不是纯计算的,也可能不是以异步取消安全的方式编写的。 POSIX只指定了三个异步取消安全函数:pthread_cancel(3)pthread_setcancelstate(3)pthread_setcancelmode(3) -参见IEEE 1003.1,2013年版,2.9.5。此取消模式只适用于不调用(纯计算)库函数的纯计算任务;如果线程被设置为在默认延迟取消模式下运行,这种代码将不会提供取消点。因此,定义这种模式的理由。 通过在关键部分禁用取消,可以编写异步取消安全代码.但是,库编写人员(包括POSIX库实现者)一般不应该出于遵循常规、避免复杂性甚至避免性能开销的原因而关心异步安全性。因为库编写人员不应该关心这个问题,所以除非另有明确说明,否则您永远不应该期望异步安全。 如果您的代码不是异步安全的(例如,调用其他库,包括POSIX/标准C库而不临时禁用取消或更改取消模式)和异步取消,则可能会泄漏资源(内存等),留下不一致的状态并锁定互斥锁死锁其他线程,并调用当前可想象和不可想象的许多其他问题。(如果您是用C++编写的,那么由于POSIX线程取消与异常处理的密切关联,您似乎还需要处理其他问题。)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17719933

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档