mikej
V2EX  ›  Node.js

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

  •  
  •   mikej · Jan 23, 2014 · 6765 views
    This topic created in 4563 days ago, the information mentioned may be changed or developed.
    刚刚踏入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 replies    1970-01-01 08:00:00 +08:00
    judasnow
        1
    judasnow  
       Jan 23, 2014
    我推荐这篇文章给你,注意看那个图。
    ----
    大概说一下我自己的理解,nodejs 采用一个 "事件循环(event loop)" 这是一个单独的线程,在nodejs执行的过程中是不会退出的。另外还有很多"工作线程(worker)"。其中"工作线程是按需生成的"其完成之后会返回到“事件循环”中(通过callback)。
    ----
    现在来看你的疑问:
    1 是不是I/O操作是与cpu无关,I/O完成之后线程再继续执行?
    io操作过程中 是几乎不需要 cpu 参与的 (通过dma控制器),对于 io 操作,系统(操作系统)会产生一个中断,并将当前线程调度到阻塞状态。io完成后 会将其加入待执行队列中 等待调度。

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

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

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

    异步的起床要出门:
    洗澡(20分钟)
    刷牙(5分钟)
    喂狗(5分钟) => 需要(40分钟)
    穿衣服(5分钟)
    找钥匙(40分钟)
    mikej
        7
    mikej  
    OP
       Jan 23, 2014
    @MichaelYin 深知!光表面的理解肯定是不够的,必须经过大量的编程实践才能理解。ps:我是做php开发的
    yyfearth
        8
    yyfearth  
       Jan 23, 2014
    简单来说,同步执行,主线程必须等待任务一一执行完毕,总的执行时间是单纯的加法
    异步执行,由于任务可以请求发出后不需要等待,多个任务可以重叠执行,所以主线程的执行等待时间减少
    pfitseng
        9
    pfitseng  
       Jan 23, 2014 via Android
    @judasnow 看到dma 顺便请教下,在arm 编制kernel 的时候好像没dma 选项,那就是都靠cpu 了?
    judasnow
        10
    judasnow  
       Jan 23, 2014
    @pfitseng 不是很了解 arm 哈,你可以 google 一下 :-)不过我觉的 arm 中肯定涉及 dma。 全靠 cpu 效率太低。
    judasnow
        11
    judasnow  
       Jan 23, 2014
    另外,看了楼主是做 php 开发的,我觉的楼主可以考虑下 如何在 php 中模拟(注意是模拟)异步操作,可能有更助于理解 nodejs 的运行模型。
    judasnow
        12
    judasnow  
       Jan 23, 2014
    mikej
        13
    mikej  
    OP
       Jan 23, 2014
    @judasnow 恩啊,多谢,还得慢慢研究啊。
    tonitech
        14
    tonitech  
       Jan 24, 2014
    @zythum 这个比喻很好!
    bombless
        15
    bombless  
       Jan 24, 2014   ❤️ 1
    这个东西考虑起来实际上挺绕的……
    其实整体来说效果是这样的:不管同步还是异步,你I/O消耗多少时间其实是不变的。而CPU时间它是客观流动的。所以在较抽象的层次也就是nodejs这一层,实际的效果就是,两者的差别在于在I/O完成之前的那些CPU时间可以被异步应用利用掉,但同步的应用无法利用掉这些时间。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   5546 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 60ms · UTC 06:46 · PVG 14:46 · LAX 23:46 · JFK 02:46
    ♥ Do have faith in what you're doing.