异步 I/O 和异步函数有什么区别?

13

Node.js是一种异步I/O。这实际上意味着什么?

如果我通过生成另一个线程来创建异步函数,这是否与Node.js有所不同?

例如:

void asyncfuntion(){
    Thread apple = new Thread(){
       public void run(){
           ...do stuff
       }
    }
    apple.start()
}

如果有差异,我能在JavaScript中进行异步I/O操作吗?


2
你想用Java还是Javascript?你提到了node,所以我猜你想用Javascript。也就是说,你明白Java !== Javascript,对吧? - jcolebrand
基本上,我从node.js中了解到异步I/O这个术语,只是想知道异步I/O和函数之间的区别。 - TheOneTeam
1
但是Node.js只是异步I/O最近流行的实现方式之一。你有什么特别不理解的地方吗?函数是执行任务的代码片段,而异步I/O则是一种从磁盘获取数据而不会阻塞的方法。 - jcolebrand
@jcolebrand:我现在觉得我很清楚了。 - TheOneTeam
6个回答

18

异步 I/O

异步 I/O(来自维基百科)

异步 I/O,或非阻塞 I/O,是一种输入/输出处理形式, 允许在传输完成之前进行其他处理。

这意味着,如果一个进程想要执行 read()write() 的同步调用,在同步模式下,该进程必须等待硬件完成物理 I/O,以便在 IO 操作成功/失败时通知它。

而在异步模式下,一旦进程异步地发出读/写 I/O 请求,系统调用会立即返回,一旦 I/O 操作已经传递到硬件或排队在操作系统/虚拟机中。因此进程的执行不会被阻塞(因此称为非阻塞 I/O),因为它不需要等待来自系统调用的结果,稍后将接收结果。

异步函数

异步函数是一种通过“事件处理程序”(或“回调函数”)将数据返回给调用方的函数。回调函数可能在任何时候被调用(取决于异步函数完成所需的时间)。这与同步函数不同,同步函数将执行其指令,然后返回值。

…我能在 Java 中执行异步 I/O 吗?

是的,Java NIO 通过 Selector 提供了非阻塞 I/O 支持。此外,Apache MINA 是一个包含非阻塞 I/O 的网络框架。相关的SO 问题回答了这个问题。


@Gentleman:所以说,同步函数和异步I/O也是可以结合起来使用的,不是吗? - TheOneTeam
@Kit Ho,好的!只要在网上寻找非阻塞示例即可。 - Buhake Sindi
3
这可能相当于要求Kit仅在网上查找心脏手术的例子并进行操作。了解它是一回事,但当你不知道自己在看什么时去寻找它是另一回事。 - jcolebrand

6

第一个链接已失效。 - Mike M
1
使用Node.js进行异步代码设计。这是第一个正确的链接吗? - lin
使用Node.js进行异步代码设计。这是第一个正确的链接吗? - lin

4
除了@The Elite Gentleman的答案之外,node不会为异步I/O函数生成线程。在node下,所有内容都在一个单线程事件循环中运行。因此,除非绝对必要,否则应避免使用某些I/O函数的同步版本,如fs.readSync。
您可以阅读这篇优秀的博客文章以获得一些见解:http://blog.mixu.net/2011/02/01/understanding-the-node-js-event-loop/

1

我一直在调查同样的问题,因为这个异步IO模式对我来说非常新颖。我在infoq.com上找到了这个讲座,让我感到非常高兴。那个人很好地解释了异步IO实际上位于哪里(操作系统 -> 内核),以及它如何嵌入node.js作为执行IO的主要习语。享受吧!

http://www.infoq.com/presentations/Nodejs-Asynchronous-IO-for-Fun-and-Profit


0

Node.js 可以通过强制使用回调函数来实现异步 IO,使程序员能够进行异步 IO。现在的回调函数与我们长期以来在 JavaScript 中处理 DOM 事件所使用的旧异步函数类似!例如:

asyncIOReadFile(fileName, asynFuncReadTheActualContentsAndDoSomethingWithThem);
console.log('我还不知道文件里有什么')
function asynFuncReadTheActualContentsAndDoSomethingWithThem(fileContents) {
    console.log('现在我知道文件内容了:' + fileContents)
}
//通常情况下,上述程序的输出将如下所示
'我还不知道文件里有什么'
//过了一段时间后
'现在我知道文件内容了:一些二进制数据'


0

来自https://en.wikipedia.org/wiki/Asynchronous_I/O

同步阻塞 I/O

一种简单的 I/O 方法是启动访问并等待其完成。

在通信进行时会阻止程序的进度,使系统资源空闲。

异步 I/O

或者,可以启动通信,然后执行不需要完成 I/O 的处理。

任何依赖于 I/O 完成的任务...仍然需要等待 I/O 操作完成,因此仍然被阻塞,

但是其他不依赖于 I/O 操作的处理可以继续进行。

示例:

https://en.wikipedia.org/wiki/Node.js

Node.js拥有一种事件驱动的架构,能够进行异步I/O操作


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接