美文网首页
[node设计理念] 单线程异步I/O

[node设计理念] 单线程异步I/O

作者: _royalpioneer | 来源:发表于2021-02-18 22:53 被阅读0次

    内容

    node的单线程异步io模型是这样设计的:

    (1)执行异步方法,将异步的任务交给内核,不带数据返回;

    (2)继续执行其他操作

    (3)事件循环拿到异步操作完成的信号或者事件后,执行异步方法中的回调函数

    如图

    image.png

    这个设计是怎么实现的呢? 需要几个帮手,事件循环,观察者,请求对象,线程池,以下拿 fs.open 举例子:

    fs.open('<directory>', 'r+', (err, fd) =>  {
      // ...
    });
    

    我们使用fs.open, 即调用了lib中fs.js, 然后fs.js调用了c++核心模块node_file.cc, 然后判断判断平台来采取不同的操作

    image.png

    判断好平台后,node会创建一个请求对象,请求对象会保存当前所有的状态和回调函数,当前场景下的请求对象是 FSReqWrap。

    请求对象会送入IO线程池等待执行,执行完毕后会将执行结果存放在请求对象的result属性上,然后通知操作系统当前对象操作已完成,并归还线程给线程池。

    事件循环中的IO观察者会在每轮tick中检查线程池中是否有执行完成的请求,有的话,取出对应的请求对象的回调函数,并取出result作为参数(这里对应的是err 或 fd),然后执行。

    至此,一个异步IO就完成了。

    image.png

    写在后面

    首先来理解下为什么node要采用单线程异步io。

    如果是多线程,会面临各线程状态同步,锁的问题。如果是单线程同步阻塞,在多并发的情况下等待的时间会很长,而采用上述设计模型的单线程异步io能很好的规避所提的这两个问题。

    另外,javascript在服务器端编程领域上没有历史包袱,加上前端开发者对异步编程都比较熟悉,所以node就采用了单线程异步io的模型。

    其次,node是多线程的,单线程是指js是单线程执行的。

    node是由一个js执行线程和多个阻塞线程组成的线程池构成的。io异步中的一个重要帮手就是事件循环,事件循环是典型的生产者消费者模型,在windows下基于IOCP创建,在Linux下基于多线程创建(libuv自行实现)。

    参考链接

    相关文章

      网友评论

          本文标题:[node设计理念] 单线程异步I/O

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