NodeJS关于同步式I/O和异步式I/O的一点疑问?

2014-01-23 13:18:12 +08:00
 mikej
刚刚踏入NodeJS的世界,对同步式I/O和异步式I/O有点不理解。

同步式I/O:当线程的执行过程中遇到I/O操作时,通常会很耗时,这时操作系统会剥夺这个线程的cpu使用权,将资源分配给其他的工作线程,当I/O操作完毕时,再恢复其对cpu的控制。照这个意思来说,是不是I/O操作是与cpu无关,I/O完成之后线程再继续执行?

异步式I/O:当遇到I/O操作时,不会等待I/O操作完成,而只是将 I/O 请求发送给操作系统,继续执行下一条语句。当操作系统完成 I/O 操作时,以事件的形式通知执行 I/O 操作的线程,线程会在特定时候处理这个事件。这里为什么是发送给操作系统,或者说为什么操作系统会有处理I/O的能力?

先多谢各位了。。
5662 次点击
所在节点    Node.js
15 条回复
judasnow
2014-01-23 13:35:00 +08:00
我推荐这篇文章给你,注意看那个图。
----
大概说一下我自己的理解,nodejs 采用一个 "事件循环(event loop)" 这是一个单独的线程,在nodejs执行的过程中是不会退出的。另外还有很多"工作线程(worker)"。其中"工作线程是按需生成的"其完成之后会返回到“事件循环”中(通过callback)。
----
现在来看你的疑问:
1 是不是I/O操作是与cpu无关,I/O完成之后线程再继续执行?
io操作过程中 是几乎不需要 cpu 参与的 (通过dma控制器),对于 io 操作,系统(操作系统)会产生一个中断,并将当前线程调度到阻塞状态。io完成后 会将其加入待执行队列中 等待调度。

2 这里为什么是发送给操作系统,或者说为什么操作系统会有处理I/O的能力?
io操作归根到底 是由 操作系统提供的系统调用来提供的。
----
我认为你可以多了解下 计算机组成原理 以及 操作系统 这两门课的相关知识。

可以在 google 上搜索关键词: 系统调用,进程调度,dma控制器
judasnow
2014-01-23 13:35:18 +08:00
mikej
2014-01-23 14:26:25 +08:00
@judasnow 基本上解决了我的问题,那篇文章也很有用,多谢了。
MichaelYin
2014-01-23 16:23:09 +08:00
不知道楼主是否有其他语言基础,这个问题我以前也不懂,讲解的文章其实我也看过,但是真正用代码实现过后才真正明白两者的不同
建议你用py的socket,threading模块实现一个简单的服务器到客户端的小应用,把几种方式都写一遍,然后你基本对于同步异步,阻塞非阻塞会有比较深刻的认识,从我经验出发我不认为你看完这篇文章就能理解
FrankFang128
2014-01-23 16:42:17 +08:00
最好永远不要在node里调用耗时的同步方法。
zythum
2014-01-23 17:06:06 +08:00
打个比方就知道什么是同步什么是异步了

同步的起床要出门:
洗澡(20分钟)-> 刷牙(5分钟)-> 喂狗(5分钟)-> 穿衣服(5分钟)-> 找钥匙(40分钟)
需要(75分钟)

异步的起床要出门:
洗澡(20分钟)
刷牙(5分钟)
喂狗(5分钟) => 需要(40分钟)
穿衣服(5分钟)
找钥匙(40分钟)
mikej
2014-01-23 17:32:26 +08:00
@MichaelYin 深知!光表面的理解肯定是不够的,必须经过大量的编程实践才能理解。ps:我是做php开发的
yyfearth
2014-01-23 18:10:06 +08:00
简单来说,同步执行,主线程必须等待任务一一执行完毕,总的执行时间是单纯的加法
异步执行,由于任务可以请求发出后不需要等待,多个任务可以重叠执行,所以主线程的执行等待时间减少
pfitseng
2014-01-23 18:36:51 +08:00
@judasnow 看到dma 顺便请教下,在arm 编制kernel 的时候好像没dma 选项,那就是都靠cpu 了?
judasnow
2014-01-23 21:02:07 +08:00
@pfitseng 不是很了解 arm 哈,你可以 google 一下 :-)不过我觉的 arm 中肯定涉及 dma。 全靠 cpu 效率太低。
judasnow
2014-01-23 21:04:51 +08:00
另外,看了楼主是做 php 开发的,我觉的楼主可以考虑下 如何在 php 中模拟(注意是模拟)异步操作,可能有更助于理解 nodejs 的运行模型。
judasnow
2014-01-23 21:07:22 +08:00
mikej
2014-01-23 22:33:03 +08:00
@judasnow 恩啊,多谢,还得慢慢研究啊。
tonitech
2014-01-24 10:11:54 +08:00
@zythum 这个比喻很好!
bombless
2014-01-24 15:23:36 +08:00
这个东西考虑起来实际上挺绕的……
其实整体来说效果是这样的:不管同步还是异步,你I/O消耗多少时间其实是不变的。而CPU时间它是客观流动的。所以在较抽象的层次也就是nodejs这一层,实际的效果就是,两者的差别在于在I/O完成之前的那些CPU时间可以被异步应用利用掉,但同步的应用无法利用掉这些时间。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/98087

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX