POSIX线程被“暂停”是什么意思?

在对最近一个问题的评论过程中,出现了一个附属问题,即在什么时候可以预期对具有可取消性PTHREAD_CANCEL_DEFERRED的pthreads线程的取消请求起作用。 随后提到了标准和一些律师。 我并不太关心我在这个问题的评论中是否错了,但我确保我正确理解POSIX的规定。

标准中最相关的部分说

每当线程启用了可取消性并且已经以该线程作为目标取消请求,然后线程调用任何作为取消点的函数时,取消请求将在函数返回之前被执行。 如果线程启用了可取消性并且在线程作为目标进行了取消请求,而线程在取消点处被挂起,则线程应被唤醒并且取消请求将被执行。

但是,线程被“暂停”是什么意思呢? POSIX明确定义了进程的术语,但就我而言,并没有为线程定义。 另一方面,POSIX将线程暂停作为少数函数的行为之一,包括但不限于与同步对象相关的一些函数。 是否应该得出结论认为那些集体作为该术语的相关定义?

鉴于POSIX没有将线程暂停指定为read()fread()或任何常规文件或流I / O函数的行为的一部分,因此这一切都与产生此查询行的问题有关,如果一个post因I / O被阻止而没有进展,这是否意味着它被“暂停”以便取消?

正如你所说,挂起的线程在套接字读取时被阻塞,等待信号量变得可用,等等。

鉴于POSIX实现在棘手的边缘变化,并且有可能在不是取消点的函数中阻塞线程,可能是依赖于要移植的代码中的取消可能会更麻烦比它值得。

我从来没有使用它,我总是选择使用代码来显式地指示线程终止(通常是管道或队列中的消息)。 使用Communicating Sequential Processes或Actor Model系统非常容易。

这样清理可以在一个人自己的控制下完成,根据需要释放内存等。 我不知道取消的线程是否会清理它的内存(我怀疑没有),或者是否存在at_exit()类型的东西(可能存在)。 总的来说,如果线程只能通过一种方式退出,我认为应用程序行为可以得到更彻底的控制。

== ==编辑

@JohnBollinger,

使用的语言If a thread has cancelability enabled and a cancellation request is made with the thread as a target while the thread is suspended at a cancellation point可以解释为IF a thread has cancelability enabled AND IF cancelled and IF implementation suspends blocked threads AND IF the thread is blocked THEN the thread shall be awakened... 换句话说,他们将它留给了POSIX子系统的实现者。

Cygwin的select()实现没有(或者至少没有)导致线程被挂起。 相反,它会为每个文件描述符生成一个轮询线程来测试可信任的活动,因为在Windows中基本缺乏类似于select()的东西(它接近但没有雪茄.Win32 select()仅适用于套接字)。 早在20世纪80年代,select()的实现也经常以这种方式工作。

可能出于这样的原因,POSIX不愿意清楚地定义线程何时被挂起。 从历史上看,select()的许多实现都是这样的,这使得它成为标准委员会的一个雷区,可以说明一个线程何时可能会被暂停。 当然,select()引起的复杂性也适用于一个进程,但是由于POSIX确实定义了一个暂停的进程,它们似乎很奇怪它们不能/不会将定义扩展到线程。

它可能取决于如何实现线程; 你可以想象有一个不使用操作系统线程的POSIX实现(有点像在操作系统根本没有执行线程的时候早期的ADA实现),在这种实现中,被阻塞的线程可能不会被挂起(在没有CPU周期的意义上)。

线程上下文中suspend的定义:

3.107条件变量

一个同步对象,允许线程重复挂起执行,直到某个关联的谓词变为真。 执行暂停在条件变量上的线程被称为在条件变量上被阻塞。

来自: http : //pubs.opengroup.org/onlinepubs/9699919799/

这不是一个直接的答案,只是一个定义 – 对于评论来说太大了。 被阻止==暂停。

read,fread和friends是系统调用,因此它们将执行上下文切换并从内核上下文执行,直到这些函数完成。 中断内核上下文超出了pthreads的范围,因此它们不会导致取消。

我没有它的参考,但据我所知,在Posix线程的上下文中的线程暂停与它的同步对象(如futex的)有关。