美文网首页
【管子先生的Node之旅·9】阻塞与非阻塞IO

【管子先生的Node之旅·9】阻塞与非阻塞IO

作者: 管子先生 | 来源:发表于2017-10-28 15:05 被阅读0次

    阻塞

    运行下列 dome 时,必须要一条一条的顺次打印出来。
    换句话说,我在执行方法时必须要等待上一条语句执行完成后才能执行,因此阻塞了线程。

        // app.js
        console.log('hello World!');
    
        console.log('Jiaiyan');
    
        console.log('hello Jiaiyan!');
    

    非阻塞

    Node 使用了事件轮询,因此在这 setTimeout 时非阻塞的。
    换句话来说,dome 运行到 setTimeout 时,后面的 console.log() 语句被立即执行,无需等待上一条语句是否执行完成。

        // app.js
        console.log('hello World!');
    
        setTimeout(() => {
            console.log('Jiaiyan');
        }, 1000);
    
        console.log('hello Jiaiyan!');
    
    事件轮询?

    从本质上来解释,就是 Node 会先注册事件,然后不停的询问内核这些事件是否已经分发。当事件分发时,对应的回调函数就会被触发,然后继续执行下去。如果没有事件出发,则继续执行其他代码,直到有新事件时,再去执行对应的回调函数(setTimeout 仅仅是注册了一个事件,然后让程序继续执行,所以,这是异步的)。

    Node.js 单线程的世界

    众所周知,Node.js不借助任何模块是以单线程的模式运行着的。
    通过下述带么可以很好的验证这一点,以及展示它和事件轮询之间的关系:

        // app.js
        var start = Date.now();
    
        setTimeout(() => {
            console.log(Date.now() - start);
        }, 1000);
    
        setTimeout(() => {
           console.log(Date.now() - start);
        }, 2000);
    

    下面是我电脑打印出来的(单位是毫秒):

    image.png
    输出结果,明显与之前设置的不符,产生这个问题的原因,是因为事件轮询被 JavaScript 代码阻塞了。当第一个事件分发时,会执行 JavaScript 回调函数。由于回调函数执行需要一定的时间,所以下一轮的事件轮询事件就超过了设定时间。因此, JavaScript 中的 setTimeout 并不能严格的遵守时钟设置。

    如果按照事件轮询所述,正在执行任务只有一个线程,也就是说,当一个函数执行时,同一时间 不可能有第二个函数在执行,并且每一个函数都有事件延迟,相当于同一时间段内参数执行量变少,这样不更影响效率吗?Node 是如何做到高并发处理的呢?

    堆栈

    先看一段代码:

        http.createServer(function() {
            a();
        });
    
        function a() {
            b();
        }
    
        function b() {}
    

    V8 在执行第一个函数时,会创建一个公共调用堆栈。如果该函数调用另一个函数,V8 就会把它添加到堆栈上去。上述代码,一旦 Http请求到达服务,Node 会先分发一个通知。然后回调函数会被执行,并且调用堆栈会变为 a => b

    由于 Node 是运行在单线程的环境中,那么,当调用堆栈展开时,Node 就无法处理其他的请求了,那么并发量不久是为 1 了吗?是的,Node 并不是提供正真的并行操作,因为那样就需要引入更多的并行线程(后期会与大家一起学习 Node 多线程)。其实,在调用堆栈非常快的情况下你无需处理多个请求。这也就是为什说V8 和 非阻塞IO 是最好的搭配:V8 的运行速度非常快,非阻塞IO 确保了单线程在运行时,不会受到数据库访问与硬盘操作而导致挂起的事情了。

    相关文章

      网友评论

          本文标题:【管子先生的Node之旅·9】阻塞与非阻塞IO

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