NodeJS关于同步式I/O和异步式I/O的一点疑问? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
mikej
V2EX    Node.js

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

  •  
  •   mikej 2014-01-23 13:18:12 +08:00 6227 次点击
    这是一个创建于 4345 天前的主题,其中的信息可能已经有所发展或是发生改变。
    刚刚踏入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的能力?

    先多谢各位了。。
    15 条回复    1970-01-01 08:00:00 +08:00
    judasnow
        1
    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
        2
    judasnow  
       2014-01-23 13:35:18 +08:00   1
    mikej
        3
    mikej  
    OP
       2014-01-23 14:26:25 +08:00
    @judasnow 基本上解决了我的问题,那篇文章也很有用,多谢了。
    MichaelYin
        4
    MichaelYin  
       2014-01-23 16:23:09 +08:00
    不知道楼主是否有其他语言基础,这个问题我以前也不懂,讲解的文章其实我也看过,但是真正用代码实现过后才真正明白两者的不同
    建议你用py的socket,threading模块实现一个简单的服务器到客户端的小应用,把几种方式都写一遍,然后你基本对于同步异步,阻塞非阻塞会有比较深刻的认识,从我经验出发我不认为你看完这篇文章就能理解
    FrankFang128
        5
    FrankFang128  
       2014-01-23 16:42:17 +08:00 via Android
    最好永远不要在node里调用耗时的同步方法。
    zythum
        6
    zythum  
       2014-01-23 17:06:06 +08:00
    打个比方就知道什么是同步什么是异步了

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

    异步的起床要出门:
    洗澡(20分钟)
    刷牙(5分钟)
    喂狗(5分钟) => 需要(40分钟)
    穿衣服(5分钟)
    找钥匙(40分钟)
    mikej
        7
    mikej  
    OP
       2014-01-23 17:32:26 +08:00
    @MichaelYin 深知!光表面的理解肯定是不够的,必须经过大量的编程实践才能理解。ps:我是做php开发的
    yyfearth
        8
    yyfearth  
       2014-01-23 18:10:06 +08:00
    简单来说,同步执行,主线程必须等待任务一一执行完毕,总的执行时间是单纯的加法
    异步执行,由于任务可以请求发出后不需要等待,多个任务可以重叠执行,所以主线程的执行等待时间减少
    pfitseng
        9
    pfitseng  
       2014-01-23 18:36:51 +08:00 via Android
    @judasnow 看到dma 顺便请教下,在arm 编制kernel 的时候好像没dma 选项,那就是都靠cpu 了?
    judasnow
        10
    judasnow  
       2014-01-23 21:02:07 +08:00
    @pfitseng 不是很了解 arm 哈,你可以 google 一下 :-)不过我觉的 arm 中肯定涉及 dma。 全靠 cpu 效率太低。
    judasnow
        11
    judasnow  
       2014-01-23 21:04:51 +08:00
    另外,看了楼主是做 php 开发的,我觉的楼主可以考虑下 如何在 php 中模拟(注意是模拟)异步操作,可能有更助于理解 nodejs 的运行模型。
    judasnow
        12
    judasnow  
       2014-01-23 21:07:22 +08:00
    mikej
        13
    mikej  
    OP
       2014-01-23 22:33:03 +08:00
    @judasnow 恩啊,多谢,还得慢慢研究啊。
    tonitech
        14
    tonitech  
       2014-01-24 10:11:54 +08:00
    @zythum 这个比喻很好!
    bombless
        15
    bombless  
       2014-01-24 15:23:36 +08:00   1
    这个东西考虑起来实际上挺绕的……
    其实整体来说效果是这样的:不管同步还是异步,你I/O消耗多少时间其实是不变的。而CPU时间它是客观流动的。所以在较抽象的层次也就是nodejs这一层,实际的效果就是,两者的差别在于在I/O完成之前的那些CPU时间可以被异步应用利用掉,但同步的应用无法利用掉这些时间。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1442 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 16:44 PVG 00:44 LAX 08:44 JFK 11:44
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86