非阻塞(事件驱动的I / O)与阻塞I / O

最近我偶然发现了一个名为nodeJS的漂亮的JS库,它就像服务器端的JS一样。

语言的主要特点是使用I / O,它使I / O的固有容量完全无阻塞使用callback!

我的问题是,如果这种完全不阻塞的I / O机制过去存在(给定事件驱动的I / O已经存在很长时间了),为什么它们在C#和高级语言Java(尽pipeJava有支持非阻塞I / O的NIO实现)?

目前,简单的文件读/写操作导致完全的I / O阻塞,事件驱动的I / O不是这种情况。

我想更好地理解事件驱动的I / O,以及它与我们在Java中的不同之处。

Java: http : //en.wikipedia.org/wiki/New_I/O

用于编写可伸缩服务器的多路复用,非阻塞I / O工具

.NET: http : //msdn.microsoft.com/en-us/library/dxkwh6zw.aspx

public IAsyncResult BeginReceive( byte[] buffer, int offset, int size, SocketFlags socketFlags, AsyncCallback callback, Object state ) 

Tcl有20年代事件驱动的I / O(如果我没有弄错的话)。 肯定在2000年之前,因为在2000年某个时候tclhttpd在基准testing中击败了Apache,人们才真正开始关注非阻塞I / O。 当人们看到这些,他们开始重新编写Web服务器。 其中一个早期的结果就是Lighttpd:用C编写的第一个非阻塞的Web服务器之一。当时,通过fileevent命令在tcl中使用事件驱动的I / O已经被认为是tcl世界的标准惯例。

AOLserver曾经(现在还有)拥有一个tcl核心,它在networking上托pipe着一个最繁忙的网站(至less在早期): http : //www.aol.com/ 。 尽pipe服务器本身是用C编写的,但它使用tcl的C API来实现事件处理和I / O。 AOLserver使用tcl的I / O子系统的原因是因为它使用tcl作为脚本语言,开发人员认为,因为别人写了它,那么也可以使用它。

我相信AOLserver是在1995年第一次发布的。这应该证实事件驱动的I / O在20世纪90年代中期已经在tcl中可用。

Tcl是最早的语言之一,如果不是最早的事件驱动引擎的语言。 事件子系统最初是为Tk库实现的,后来被合并到了tcl本身。

据我所知,人们普遍认为multithreading比事件驱动更容易,因为在multithreading编程中,每个线程都有一个简单的顺序执行stream程,而事件驱动由许多小的代码片段组成。

当然,这在其他地方更好说明,例如参见状态线程FAQ的 Q.2。

即使对于基本的文件I / O,Java也有不好的支持。 创build这些语言是为了快速创build可移植的GUI应用程序,而不是用于优化和操作系统相关的低级I / O操作。