2014-03-27 232 views
0

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

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

+0

你可以找到更多关于操作系统设计的书籍。特别是对于Windows,您拥有Mark Russinovich的Microsoft Windows Internals。 –

回答

1

朦胧的观点是什么在继续...主要关注IO。

的Unix/Linux/POSIX的

Unix的等同,选择(),epoll的(),以及类似的已经以各种方式实现。在早期,这些实现是垃圾,并且仅仅是占用所有CPU时间的繁忙轮询循环。现在它好多了,并且在被阻塞时不需要CPU时间。

他们可以做到这一点我认为,因为像以太网,串口等设备的设备驱动模型已被设计为支持select()系列功能。具体来说,模型必须允许内核告诉设备在发生事件时引发中断。内核然后可以决定是否会导致select()解锁等等,结果是有效的进程阻塞。

视窗

在Windows中,WaitfFor当应用于异步IO是完全不同的。您实际上必须从IO设备开始线程读取,并且当读取完成时(请注意,无法启动),您将该线程返回唤醒WaitFor的东西。它会在object.beginread()等中被打扮,但它们都归结为底层。

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

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

CYGWIN,UNIX在Windows

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

我敢打赌整个5新便士,这也是MS如何选择套接字。

我的经验,迄今

Windows的WaitFors ......都很好,这是保证完成或继续和好固定的阶段操作,但非常不愉快的不属于操作(如IO)。取消异步IO操作令人非常不愉快。我发现这样做的唯一方法是关闭设备,插座,管道等,这并不总是你想做的。

尝试回答这个问题

硬件的中断系统支持的执行选择(),因为它的设备来通知有什么东西,而不必轮询/旋CPU发生的CPU的方式在设备上的寄存器中。 Unix/Linux使用该中断系统提供select()/ epoll()功能,并且还将纯粹的内部“设备”(管道,文件等)合并到该功能中。

Windows的等效工具WaitForMultipleObjects()基本上不包含任何类型的IO设备,这就是为什么在等待该线程完成时必须有一个单独的线程为您做IO。硬件上的中断系统(我猜测)仅用于在读取或写入操作完成时告诉设备驱动程序。例外是Windows中的select()函数调用,它只在套接字上运行,而不是其他任何东西。

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

臆测

我猜测的原因的Windows从来没有做过一个select()是正确的为Windows早期的设备驱动程序能够在没有办法支持它,有点像早期的Linux。

但是,Windows在很早以前就变得非常流行,并且大量的设备驱动程序都是针对(有缺陷的)设备驱动程序标准编写的。

如果MS在任何时候都想过“也许我们会更好地改进这个问题”,那么他们将面临让所有人重写设备驱动程序这一大规模事业的问题。所以他们决定不去实现单独的IO线程/ WaitFor ...模型。这被MS推广为优于Unix的做事方式。现在Windows已经这么长时间了,我猜测MS中没有人认为事情可以改进。

== ==编辑

因为我已经偶然发现Named Pipes - Asynchronous Peeking。这很吸引人,因为看起来(我很高兴地说)几乎揭穿了我对Windows和IO的所有想法。这篇文章适用于管道,尽管它可能也适用于任何IO流。

它似乎取决于启动异步读取操作来读取零字节。直到有一些字节可用,读取才会返回,但是没有一个从流中读取。因此,您可以使用类似WaitForMultipleObjects()的方法来等待多个这样的异步操作完成。

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

我还没有机会尝试使用它,但是如果它确实有效,那么这意味着可以在Windows上实现与Unix的select()等效的东西,因此它必须始终得到支持直至设备驱动程序级别和中断。因此,上面的广泛删除...

+1

它在我看来好像你并不真正了解Windows设计,以及它在你认为比较低劣的* nix中的变化。 –

+0

@DavidHeffernan,你可能已经注意到我的前缀警告“朦胧景观”。现在,如果你认为自己更清楚,那么为什么不作出积极的贡献,而不是故意忽视别人自己的警告? – bazza

+1

我不是“如果你不能做得更好,剔除”防守的粉丝。我不是权威,知道什么时候什么都不说。 –