美文网首页
Node异步式I/O和异步式编程(三)

Node异步式I/O和异步式编程(三)

作者: simuty | 来源:发表于2016-10-11 14:37 被阅读110次

    Node.js 最大的特点就是异步式 I/O(或者非阻塞I/O)与事件紧密结合的编程模式。

    第一部分: I/O

    1.阻塞I/O与非阻塞I/O概念

    1.1阻塞I/O(同步I/O)
    线程在执行中如果遇到磁盘读写或网络通信(统称为I/O 操作), 通常要耗费较长的时间,这时操作系统会剥夺这个线程的 CPU 控制权,使其暂停执行,同时将资源让给其他的工作线程,这种线程调度方式称为阻塞,当I/O 操作完成时,操作系统将这个线程的阻塞解除,恢复其对CPU的控制 ,令其继续运行。这种 I/O 模式就是通常的同步式 I/O(Synchronous I/O)或阻塞式 I/O (Blocking I/O)。
    1.2非阻塞I/O(异步I/O)
    非阻塞I/O是针对所有的I/O不采用阻塞的策略, 当线程遇到I/O 操作时, 不会阻塞等待完成, 而是将I/O 操作发送给操作系统, 继续执行下一个语句, 等操作系统完成I/O 操作以后, 会以事件的形式发送通知执行I/O 操作的线程, 线程会在特定的时候处理这个事件; 也就是线程中会不停的监听时间循环, 看是否有未处理的事件, 并以此处理.

    举个通俗的例子:

    例子来自知乎网友

    你打电话问书店老板有没有《分布式系统》这本书,如果是`同步通信机制`,书店老板会说,你稍等,”我查一下",
    然后开始查啊查,等查好了(可能是5秒,也可能是一天)告诉你结果(返回结果)。
    
    而`异步通信机制`,书店老板直接告诉你我查一下啊,查好了打电话给你,然后直接挂电话了(不返回结果)。
    然后查好了,他会主动打电话给你。在这里老板通过“回电”这种方式来回调。
    
    
    2.阻塞I/O与非阻塞I/O特点
    同步I/O(阻塞式) 异步I/O(非阻塞式)
    利用多线程提供吞吐量 单线程可实现高吞吐量
    通过事件分割和线程调度利用多核CPU 通过功能划分利用多核CPU
    需要由操作系统调度多线程使用多核CPU 可以将单进程绑定到单核 CPU
    难以充分利用 CPU 资源 可以充分利用 CPU 资源
    符合线性的编程思维 不符合传统编程思维
    屏幕快照 2016-10-11 上午10.31.09.png

    第二部分 异步式编程(函数式编程)

    有异步I/O,就必然有异步编程。
    首先以同步式编程的语法读取一个文件:

    创建readfilesync.js, 并执行

    var fs = require('fs');
    var data = fs.readFileSync('/Users/51testing/Desktop/file.txt', 'utf-8'); 
    console.log(data);
    console.log('end.');     
    

    打印的结果如下:

    //执行
    $ node /Users/51testing/Desktop/readfilesync.js 
    你好呀
    end.
    $ 
    

    以上代码很容易理解, 自上而下的执行, 那么异步编程的做法呢?

    创建readfileasync.js, 并执行

    var fs = require('fs');
    fs.readFile('/Users/51testing/Desktop/file.txt', 'utf-8', function(err, data) {
    if (err){ 
        console.error(err);
    } else { 
        console.log(data);
    } 
    });
        console.log('end.');
    

    打印的结果如下:

    //执行
    $ node /Users/51testing/Desktop/readfileasync.js 
    end.
    你好呀
    $ 
    

    fs.readFile 调用时所做的工作只是将异步式 I/O 请求发给了操作系统, 然后立即返回并执行后面的语句,执行完以后进入事件循环监听事件。 fs 接到I/O 请求完成的事件时,事件循环会主动调用回调函数以完成后续工作。因此我们会先看到 end.然后看到 file.txt 文件的内容。

    第三部分 Node.js循环机制

    屏幕快照 2016-10-08 上午11.32.40.png

    Node.js 在什么时候会进入事件循环呢?

    生命周期为:Node.js 程序由事件循环环开始,到事件循环结束.

    所有的逻辑都是事件的回调函数,所以 Node.js 始终在事件循环中,程序入口就是 事件循环第一个事件的回调函数。事件的回调函数在执行的过程中,可能会发出 I/O 请求或直接发射 (emit)事件,执行完成后再返回事件 循环,事件循环会会检查循环中有没有 处理的事件,直到到程序结束。

    参考链接
    Node.js开发指南
    深入浅出Node.js

    更多精彩内容请关注“IT实战联盟”哦~~~


    IT实战联盟.jpg

    相关文章

      网友评论

          本文标题:Node异步式I/O和异步式编程(三)

          本文链接:https://www.haomeiwen.com/subject/kcxbyttx.html