代码之家  ›  专栏  ›  技术社区  ›  Qiulang

如果没有while true循环,nodejs事件循环如何保持运行?

  •  0
  • Qiulang  · 技术社区  · 4 年前

    Nodejs Event Loop "Event Loop Explained" Don't Block the Event Loop

    我认为nodejs代码(js或c++)中不存在for/while-forever循环,例如这里解释的libev事件循环 http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod#EXAMPLE_PROGRAM

    int
       main (void)
       {
         // use the default event loop unless you have special needs
         struct ev_loop *loop = EV_DEFAULT;
    
        // init
    
        // now wait for events to arrive
        ev_run (loop, 0);
    
        // break was called, so exit
        return 0;
     }
    

    那么nodejs事件循环是如何永远运行的,或者可能确实存在一个for/while永远循环,如 https://en.wikipedia.org/wiki/Event_loop 伪代码显示?

    我搜索了所有SO网站,找到了 Is an event loop just a for/while loop with optimized polling? . 有不同的意见,例如布赖恩·奥克利的回答是肯定的,其他人说不是。

    0 回复  |  直到 4 年前
        1
  •  1
  •   Andrey Popov    4 年前

    为什么要使用“while true”循环?尽管人们常说“这是一个无限循环”,但这并不意味着它实际上是一个循环 while

    正如您在“事件循环解释”中所读到的,在事件循环周期中有不同的阶段。在完成最后一个阶段后,它基本上会在短时间内自行休眠,然后再次从第一个阶段开始。众所周知,在浏览器中,使用 setTimeout(callback, 0) 4 or more 毫秒,这意味着至少4ms的周期之间存在间隔。

    startEventLoopPhaseExecution() {
      processEventLoopPhases();
      restABit(); // synchronously do nothing for some time
      startEventLoopPhaseExecution(); // start from phase 1 again
    }
    
        2
  •  0
  •   Qiulang    4 年前

    安德烈的意见和这篇文章 Event loop in JavaScript 我进一步检查了libuv的源代码,它确实是一个while循环,

    https://github.com/libuv/libuv/blob/v1.x/src/unix/core.c#L369

    int uv_run(uv_loop_t* loop, uv_run_mode mode) {
     ...
      r = uv__loop_alive(loop);
      if (!r)
        uv__update_time(loop);
    
      while (r != 0 && loop->stop_flag == 0) {
    

    https://github.com/libuv/libuv/blob/v1.x/src/win/core.c#L596 基本上是一样的

    int uv_run(uv_loop_t *loop, uv_run_mode mode) {
       ...
       while (r != 0 && loop->stop_flag == 0) {
    

    起初我不清楚nodejs是使用libev还是libuv中实现的事件循环,但这是另一个主题。

    我检查了运行ev_的libev源代码 https://github.com/enki/libev/blob/master/ev.c#L3547

    它也是一个 do while 所以我想我只是问了一个愚蠢的问题。