libuv library study notes-advanced-event-loops

Advanced event loops

libuv provides a lot of ways to control the event-loop, you can use multiple loops to achieve many interesting functions. You can also embed libuv's event loop into other event-loop-based libraries. For example, imagine a Qt-based UI, and then Qt's event-loop is driven by libuv, doing enhanced system tasks.

Stopping an event loop

uv_stop()Used to terminate the event loop. The earliest time the loop will stop is at the next iteration, or a little later. This means that the events that are ready to be processed in this cycle will still be processed and uv_stopwill not work. When uv_stopcalled, loop will not be blocked by IO operations in the current loop. The above is a bit mysterious, let us look at uv_run()the following code:

src/unix/core.c - uv_run

int uv_run(uv_loop_t* loop, uv_run_mode mode) {
    
    
  int timeout;
  int r;
  int ran_pending;

  r = uv__loop_alive(loop);
  if (!r)
    uv__update_time(loop);

  while (r != 0 && loop->stop_flag == 0) {
    
    
    uv__update_time(loop);
    uv__run_timers(loop);
    ran_pending = uv__run_pending(loop);
    uv__run_idle(loop);
    uv__run_prepare(loop);

    timeout = 0;
    if ((mode == UV_RUN_ONCE && !ran_pending) || mode == UV_RUN_DEFAULT)
      timeout = uv_backend_timeout(loop);

    uv__io_poll(loop, timeout);

stop_flagby uv_stopsetting. Now all libuv callback functions are called in a loop cycle, so calling uv_stopdoes not abort this cycle. First, libuv will update the timer, then run the next timers, idle and prepare callbacks, and call any prepared IO callback functions. If you call at any time between them, uv_stop()will stop_flagbe set to 1. This results in uv_backend_timeout()0 being returned, which is why the loop does not block on I/O. From another point of view, you call it in any check handler uv_stop, and the I/O has been completed at this time, so it has no effect.

When the result has been obtained or an error occurs, uv_stop()it can be used to close a loop, and there is no need to guarantee the order in which handlers stop.

The following is a simple example, which demonstrates that the loop is stopped, and the current loop is still executing.

uvstop/main.c

#include <stdio.h>
#include <uv.h>

int64_t counter = 0;

void idle_cb(uv_idle_t *handle) {
    
    
    printf("Idle callback\n");
    counter++;

    if (counter >= 5) {
    
    
        uv_stop(uv_default_loop());
        printf("uv_stop() called\n");
    }
}

void prep_cb(uv_prepare_t *handle) {
    
    
    printf("Prep callback\n");
}

int main() {
    
    
    uv_idle_t idler;
    uv_prepare_t prep;

    uv_idle_init(uv_default_loop(), &idler);
    uv_idle_start(&idler, idle_cb);

    uv_prepare_init(uv_default_loop(), &prep);
    uv_prepare_start(&prep, prep_cb);

    uv_run(uv_default_loop(), UV_RUN_DEFAULT);

    return 0;
}

Guess you like

Origin blog.csdn.net/DeepLearning_/article/details/131949933