PIPES使用什么机制来“唤醒”PIPES?收件人?
我有两个问题,其中之一就是这里。
在 Windows 上,我熟悉管道及其工作原理。但是,我很好奇操作系统使用什么机制来通知接收者线程消息到达。
线程是否连续“轮询和睡眠”以获取数据?操作系统是否检查线程是否正在休眠并将其唤醒?或者是否使用了其他机制?
具体来说,我想构建一个IPC系统,其中许多线程需要传递消息。我不需要使用管道,但我确实需要知道最有效的通知方法。
I have two questions is one here.
On Windows, I am familiar with pipes and how they work. However, I am curious as to what mechanism the OS uses to notify the recipient thread of a message arrival.
Does the thread "poll & sleep" continuously for data? Does the OS check to see if the thread is sleeping and wake it up? Or is there some other mechanism used?
Specifically, I want to build an IPC system where many threads need to pass messages. I don't need to use pipes, but I do need to know the most efficient notification method possible.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
开发人员可以决定如何使用管道,是否要睡眠/轮询,或者要调用阻塞函数并等待数据可用。
关于管道用于唤醒进程的机制(假设进程处于阻塞读取调用中),负责的不是管道,而是操作系统,就像任何其他操作系统调用一样:它注册操作并阻塞进程/线程,直到数据可用。当数据可用时,它完成系统调用。
The developer can decide how they want to work with the pipe, whether they will sleep/poll or else they want to call blocking functions and wait until the data is available.
About the mechanism that the pipe has for waking up the process --assuming that the process is in a blocking read call-- it is not the pipe, but the OS the one that takes charge, like in any other OS call: it registers the operation and blocks the process/thread until the data is available. When the data is available, it completes the system call.
这是 Unix 的答案。我认为 Windows 非常相似,因为该解决方案已经存在很长时间并且众所周知是强大的。细节会略有不同(不同的 API 调用、语义细节等),
这取决于另一端是否以阻塞模式或非阻塞模式使用管道的文件描述符。
在阻塞模式下,进程在操作系统内核中等待数据可用。通知发生的方式取决于操作系统。它很可能涉及一个被认为是可运行的进程队列,并且由于内核可以(很大程度上)控制中断它的因素,一切都变得更简单。在一个简单的(单处理器)实现中,您可以做一些琐碎的事情,例如在写入管道时注意到其他进程正在等待从中读取(通过某种“兴趣集”),从而将读取器标记为可运行在那一点(此时由调度程序决定)。
在非阻塞模式下,进程要么不时轮询(哎呀!),要么使用像
select()
或poll()
这样的系统调用(还有一些更高性能的变体)。这与 Windows 调用WaitForMultipleObjects()
非常相似,并且与管道配合得很好。依次返回到可运行进程队列、兴趣集和调度程序。由于管道已满或管道为空而阻塞也并不重要,因为控制流在读取器和写入器之间几乎是对称的。 (当然,与数据流不同。)
This is an answer for Unix. I'd lay good money on Windows being pretty similar as the solution has been around a long time and is well known to be robust. The details will vary a bit (different API calls, specifics of semantics, etc.)
It depends on whether the other end is using the pipe's file descriptor in blocking or non-blocking mode.
In blocking mode, the process is waiting in the OS kernel for the data to become available. The way in which notification happens there depends on the OS. Chances are it involves a queue of processes that are considered to be runnable, and everything's made simpler by the fact that the kernel can (largely) control what interrupts it. In a simple (single processor) implementation you could go for something as trivial as noting on write to the pipe that the other process is waiting to read from it (via some kind of “interest set”), and so marking the reader as runnable at that point (at which time it becomes up to the scheduler to decide).
In non-blocking mode, either the process is polling from time to time (yuck!) or they're using a system call like
select()
orpoll()
(there are some higher-performance variants too). That's very much like the Windows callWaitForMultipleObjects()
and works just great with pipes. That in turn ends up back at that runnable process queue, the interest set, and the scheduler.It also doesn't really matter too much whether it's blocking because the pipe is full or the pipe is empty, as the control flow is pretty much symmetric between readers and writers. (Unlike the data flow, of course.)