简体   繁体   English

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

[英]What does it mean to POSIX that a thread is “suspended”?

In the course of commentary on a recent question , a subsidiary question arose about at what point a cancellation request for a pthreads thread with cancelability PTHREAD_CANCEL_DEFERRED can be expected to be acted upon. 在对最近一个问题的评论过程中,出现了一个附属问题,即在什么时候可以预期对具有可取消性PTHREAD_CANCEL_DEFERRED的pthreads线程的取消请求采取行动。 References to the standard and a bit of lawyering ensued. 随后提到了标准和一些律师。 I'm not much concerned specifically about whether I was mistaken in my comments on that question, but I would like to be sure I understand POSIX's provisions correctly. 我并不太关心我在这个问题的评论中是否错了,但我确定我正确理解POSIX的规定。

The most pertinent section of the standard says 标准中最相关的部分说

Whenever a thread has cancelability enabled and a cancellation request has been made with that thread as the target, and the thread then calls any function that is a cancellation point [...], the cancellation request shall be acted upon before the function returns. 每当线程启用了可取消性并且已经以该线程作为目标取消请求,然后线程调用任何作为取消点的函数时,取消请求将在函数返回之前被执行。 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, the thread shall be awakened and the cancellation request shall be acted upon. 如果线程已启用可取消性并且在线程作为目标进行取消请求,而线程在取消点处被挂起,则线程应被唤醒并且应取消取消请求。

What, though, does it mean for a thread to be "suspended"? 但是,线程被“暂停”是什么意思呢? POSIX explicitly defines the term for processes, but not, as far as I can determine, for threads. POSIX明确定义了进程的术语,但就我所知,对于线程没有明确定义。 On the other hand, POSIX documents thread suspension to be among the behaviors of a handful of functions, including, but not limited to, some of those related to synchronization objects. 另一方面,POSIX将线程暂停作为少数函数的行为之一,包括但不限于与同步对象相关的一些函数。 Should one then conclude that those serve collectively as the relevant definition of the term? 是否应该得出结论认为那些集体作为该术语的相关定义?

And as this all pertains to the question that spawned this line of inquiry, given that POSIX does not specify thread suspension as part of the behavior of read() , fread() , or any of the general file or stream I/O functions, if a thread is not making progress on account of being blocked on I/O, does that necessarily mean it is "suspended" for the purposes of cancellation? 鉴于POSIX没有将线程暂停指定为read()fread()或任何常规文件或流I / O函数的行为的一部分,因此这一切都与生成此查询行的问题有关,如果一个帖子由于在I / O上被阻止而没有取得进展,这是否意味着它被“暂停”以便取消?

A suspended thread is one that, as you say, is blocked on a socket read, waiting for a semaphore to become available, etc. 如你所说,挂起的线程在套接字读取时被阻塞,等待信号量变得可用,等等。

Given that POSIX implementations vary at the tricky edges, and that there is the potential for a thread to be blocked in a function that is not a cancellation point, it might be that relying on cancellation in code that is to be ported might be more trouble than it's worth. 鉴于POSIX实现在棘手的边缘变化,并且有可能在不是取消点的函数中阻塞线程,可能依赖于要移植的代码中的取消可能更麻烦比它值得。

I've never used it, I've always chosen to have code to explicitly instruct a thread to terminate (normally a message down a pipe or queue). 我从来没有使用它,我总是选择使用代码来明确地指示线程终止(通常是管道或队列中的消息)。 This is very easy with a Communicating Sequential Processes or Actor Model system. 使用Communicating Sequential Processes或Actor Model系统非常容易。

That way clean up can be done under one's own control, freeing memory, etc. as necessary. 这样清理可以在一个人自己的控制下完成,根据需要释放内存等。 I've no idea whether a cancelled thread will clean up its memory (I suspect not), or whether there is the option for an at_exit() type thing (there may be). 我不知道取消的线程是否会清理它的内存(我怀疑没有),或者是否存在at_exit()类型的东西(可能存在)。 On the whole I think that application behaviour is more thoroughly controlled if there is only one single way a thread can exit. 总的来说,我认为如果线程只有一种方式可以退出,那么应用程序行为就会得到更彻底的控制。

==EDIT== == ==编辑

@JohnBollinger, @JohnBollinger,

The language used 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 could be interpretted as 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... . 使用的语言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... In other words, they're leaving it up to the implementer of the POSIX subsystem. 换句话说,他们将它留给了POSIX子系统的实现者。

Cygwin's implementation of select() does not (or at least did not) result in the thread being suspended. Cygwin的select()实现没有(或者至少没有)导致线程被挂起。 Instead it spawns a polling thread per file descriptor to test for signalable activity, due to the fundamental lack of anything quite like select() in Windows (it gets close, but no cigar. Win32 select() works on only sockets). 相反,它会为每个文件描述符生成一个轮询线程来测试可信任的活动,因为在Windows中基本缺乏像select()这样的东西(它接近,但没有雪茄.Win32 select()仅适用于套接字)。 Implementations of select() back in the 1980s often worked this way too. 早在20世纪80年代,select()的实现也经常以这种方式工作。

It might be for reasons like this that POSIX is reluctant to clearly define when a thread is suspended. 可能出于这样的原因,POSIX不愿意清楚地定义线程何时被挂起。 Historically many implementations of select() were like this, making it a minefield for a standards committee to say when a thread might or might not be suspended. 从历史上看,select()的许多实现都是这样的,这使得它成为标准委员会的一个雷区,可以说明线程何时可能被暂停或者可能不会被暂停。 Of course the complexities caused by select() would also apply to a process but as POSIX does define a suspended process it does seem odd that they couldn't / didn't extend the definition to threads. 当然,select()引起的复杂性也适用于一个进程,但是由于POSIX确实定义了一个暂停的进程,它们似乎很奇怪它们不能/不会将定义扩展到线程。

It might be down to how threads are implemented; 它可能取决于如何实现线程; you can conceivably have a POSIX implementation that doesn't use OS threads (a bit like the early implementations of ADA back in the days when OSes didn't do threads at all), and in such an implementation a blocked thread might not be suspended (in the sense of taking no CPU cycles) at all. 你可以想象有一个不使用操作系统线程的POSIX实现(有点像在操作系统根本没有执行线程的时候早期的ADA实现),在这种实现中,被阻塞的线程可能不会被暂停(在没有CPU周期的意义上)。

Definition of suspend in the context of threads: 在线程的上下文中定义suspend:

3.107 Condition Variable 3.107条件变量

A synchronization object which allows a thread to suspend execution, repeatedly, until some associated predicate becomes true. 一个同步对象,允许线程重复暂停执行,直到某个关联的谓词变为真。 A thread whose execution is suspended on a condition variable is said to be blocked on the condition variable. 执行挂起在条件变量上的线程被称为在条件变量上被阻塞。

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

This is not a direct answer, just a definition – too large for a comment. 这不是一个直接的答案,只是一个定义 - 对于评论来说太大了。 Blocked == suspended. 被阻止==暂停。

read, fread, and friends are system calls and as such they will execute a context switch and execute from the kernel context until those functions complete. read,fread和friends是系统调用,因此它们将执行上下文切换并从内核上下文执行,直到这些函数完成。 Interrupting a kernel context is outside the scope of pthreads thus they will not cause a cancellation. 中断内核上下文超出了pthreads的范围,因此它们不会导致取消。

I don't have a reference for it, but as far as I know, thread suspension in the context of Posix threads has to do with it's synchronization object's ( like futex's ). 我没有它的参考,但据我所知,在Posix线程的上下文中的线程暂停与它的同步对象(如futex的)有关。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM