Wait()功能是如何实现的

时间:2014-03-27 05:30:16

标签: multithreading winapi unix linux-kernel win32-process

如何在Windows或任何操作系统内部实现等待(例如:WaitForSingleObject)功能? 与旋转锁有什么不同?

CPU /硬件是否提供了执行此操作的特殊功能?

1 个答案:

答案 0 :(得分:1)

朦胧的观点接下来......主要关注IO。

Unix / Linux / Posix

Unix等价物,select(),epoll()等已经以各种方式实现。在早期,这些实现都是垃圾,而且只比繁忙的轮询循环耗尽了所有CPU时间。现在它好多了,在阻塞时没有占用CPU时间。

我认为他们可以做到这一点,因为以太网,串口等设备的设备驱动程序模型设计用于支持select()系列函数。特别是模型必须允许内核告诉设备在发生某些事情时引发中断。然后内核可以决定是否会导致select()解锁等等。结果是有效的进程阻塞。

<强>窗

在Windows中,WaitfFor应用于异步IO时完全不同。实际上你必须从IO设备启动一个线程读取,当读取完成时(注意,不是启动),你有那个线程返回唤醒WaitFor的东西。它会在object.beginread()等中打扮,但它们都归结为底层。

这意味着您无法在Windows中复制串行,管道等的select()功能。但是有一个针对套接字的select函数调用。奇怪的。

对我来说,这表明Windows内核的整个IO架构和设备驱动程序模型只能通过要求它们执行操作并阻塞直到设备完成它来驱动设备。设备似乎没有真正的异步方式来通知内核事件,可以实现的最好方法是让一个单独的线程为您执行同步操作。我不知道他们是如何选择套接字的,但我怀疑。

CYGWIN,Windows上的Unix

当cygwin人员在Windows上实现他们的select()例程时,他们惊恐地发现除了套接字之外的其他任何东西都不可能实现。他们所做的是为每个传递给它的文件描述符选择它们会产生一个线程。这将轮询设备,管道,等待可用数据计数为非零等等。然后该线程将通知实际调用select()的线程发生了某些事情。这非常让人联想到Unix黑暗时代的select()实现,而且效率非常低。但它确实有效。

我敢打赌整个5便士那个MS也是如何为插座选择的。

我的经验远远

<德尔>视窗&#39; WaitFors ...适用于保证完成或继续进行的操作以及良好的固定阶段,但对于不是非IO的操作非常不愉快。取消异步IO操作非常不愉快。我发现这样做的唯一方法是关闭设备,插座,管道等,这并不总是你想做的事情。

尝试回答问题

硬件的中断系统支持select()的实现,因为它可以让设备通知CPU发生了什么事情,而CPU不必轮询/旋转设备中的寄存器

Unix / Linux使用该中断系统提供select()/ epoll()功能,并且还包含纯粹的内部设备&#39; (管道,文件等)到该功能。

<德尔>视窗&#39;等效设施,WaitForMultipleObjects()从根本上不包含任何类型的IO设备,这就是为什么你必须有一个单独的线程为你做IO而你等待该线程完成。硬件上的中断系统(我猜测)仅用于在读或写操作完成时告诉设备驱动程序。例外情况是Windows中的select()函数调用只能在套接字上运行,而不是其他任何东西。

Unix / Linux和Windows之间架构差异的一个重要线索就是PC可以运行,但只能在Unix / Linux上获得适当的以IO为中心的select()。

<强>臆测

我猜测Windows从未正确完成过select()的原因是Windows的早期设备驱动程序无法支持它,有点像早期的Linux。

然而,Windows很早就开始流行,而且很多设备驱动程序都是针对那个(有缺陷的?)设备驱动程序标准编写的。

如果在任何时候MS曾经想过,或许我们可以更好地改进这个&#34;他们会遇到让每个人都重写他们的设备驱动程序的问题,这是一项艰巨的任务。所以他们决定不这样做,而是实现了单独的IO线程/ WaitFor ...模型。这得到了MS的推动,因为它在某种程度上优于Unix的做事方式。现在Windows已经这么久了,我猜测MS中没有人认为事情可以改进。

== EDIT ==

我偶然发现了Named Pipes - Asynchronous Peeking。这很有吸引力,因为看起来我很想揭穿几乎所有关于Windows和IO的东西。(我很高兴地说)。本文适用于管道,但可能它也适用于任何IO流。

它似乎依赖于启动异步读取操作来读取零字节。在有一些可用字节之前,读取将不会返回,但是不会从流中读取它们。因此,您可以使用WaitForMultipleObjects()之类的东西来等待多个这样的异步操作完成。

由于接受的答案下面的评论认为这在我所阅读的所有Microsoft文档中都非常明显。我想知道它在操作系统中是一种无意识但有用的行为。我一直在通过Mark Russinovich的Windows Internals,但我还没有找到任何东西。

我还没有机会对此进行实验,但是如果它确实有效则意味着可以在Windows上实现与Unix的select()相当的东西,因此它必须一直支持到设备驱动程序级别和中断。因此,上面的广泛罢工......