Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the logic of the Libuv event loop implementation?

2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/01 Report--

This article mainly introduces "what is the logic of the implementation of the Libuv event loop". In the daily operation, I believe that many people have doubts about the logic of the implementation of the Libuv event loop. The editor consulted all kinds of materials and sorted out a simple and useful operation method. I hope it will be helpful to answer the doubt of "what is the logic of the implementation of the Libuv event loop?" Next, please follow the editor to study!

Libuv is a cross-platform event-driven asynchronous io library. But it provides not only io, but also processes, threads, signals, timers, inter-process communication, and so on.

Libuv uses event-driven modules provided by various platforms to implement asynchronous (epoll, kqueue, IOCP, event)

Ports). It is used to support the upper non-file io module. Libuv encapsulates the upper event and callback into an event-driven module that the io observer (uv__io_t) puts into the underlying layer. When the event is triggered, libuv performs a callback in the io watcher.

Libuv implements a thread pool to support the tasks of upper layer files io, dns, and user layer consumption cpu.

The overall executive architecture of Libuv

As we can see from the figure above, Libuv is divided into several phases, and then the tasks in each phase are continuously performed in a cycle. Let's take a look at each stage in detail.

1 update the current event. At the beginning of each event cycle, libuv updates the current event to the variable. The rest of the cycle may use this variable to obtain the current event to avoid excessive system calls affecting performance.

2 if the time loop is in the alive state, start processing each stage of the event loop. Otherwise, exit the event loop. What does alive status mean? If there is a handle,active state of active and ref state of request or closing state of handle, it is considered that the event loop is alive (the implementation will be analyzed later).

3 timer phase: determine which node in the smallest heap has timed out and execute its callback.

4 pending phase: execute pending callback. In general, all io callbacks (network, file, dns) are performed in the poll io phase. However, in some cases, the callback of the poll io phase is delayed until the next loop, so the callback is performed during the pending phase.

5 idle phase: if the node processes the avtive state, each event loop is executed (idle does not mean that the event loop is executed when it is idle).

6 prepare stage: same as idle stage.

7 poll io phase: calculate the maximum waiting time timeout, and calculate the rules:

If the time loop is running in UV_RUN_NOWAIT mode, timeout is 0.

If the time loop is about to exit (uv_stop is called), timeout is 0.

If there is no active status, the handle or request,timeout is 0.

If there are nodes in the queue of the dile phase, the timeout is 0.

If there is a handle waiting to be turned off (that is, uv_close is called), timeout is 0.

If none of the above is satisfied, the node with the fastest timeout in the timer phase is taken as the timeout, and if not, the timeout is equal to-1, that is, it is blocked forever until the condition is met.

8 poll io phase: call the io multiplexing interface provided by each platform, and wait for timeout at most. When returned, the corresponding callback is executed. (for example, epoll mode is used in linux)

9 check stage: the same as idle prepare.

10 closing phase: handles the callback of the handle that called the uv_close function.

If libuv is running in UV_RUN_ONCE mode, the event loop is about to exit. In one case, however, the value of the timeout of the poll io phase is the value of the node of the timer phase. And the poll io phase is returned because of a timeout, that is, no event occurs and no io callback is performed. At this point, you need to perform a timer phase. Because a node timed out.

12 an event loop ends, and if libuv is running in UV_RUN_NOWAIT or UV_RUN_ONCE mode, exit the event loop. If it is running in UV_RUN_DEFAULT mode and the state is alive, the next cycle starts. Otherwise, exit the event loop.

The following is the logic of the Libuv event loop implementation.

Int uv_run (uv_loop_t* loop, uv_run_mode mode) {

Int timeout

Int r

Int ran_pending

/ / submit the task to loop before uv_run

R = uv__loop_alive (loop)

/ / the event loop has no task to execute and is about to exit. Set the time of the current loop.

If (! r)

Uv__update_time (loop)

/ / there is no task to handle or uv_stop is called

While (r! = 0 & & loop- > stop_flag = 0) {

/ / Update the time field of loop

Uv__update_time (loop)

/ / execute timeout callback

Uv__run_timers (loop)

/ / execute pending callback. Ran_pending indicates whether the pending queue is empty, that is, no node can execute it.

Ran_pending = uv__run_pending (loop)

/ / continue to execute various queues

Uv__run_idle (loop)

Uv__run_prepare (loop)

Timeout = 0

/ / when the execution mode is UV_RUN_ONCE, blocking poll io will only occur if there is no pending node, and the default mode is also

If ((mode = = UV_RUN_ONCE & &! ran_pending) | | mode = = UV_RUN_DEFAULT)

Timeout = uv_backend_timeout (loop)

/ / poll io timeout is the timeout of epoll_wait

Uv__io_poll (loop, timeout)

Uv__run_check (loop)

Uv__run_closing_handles (loop)

/ / there is another chance to perform a timeout callback, because the poll io phase may have returned because the timer timed out.

If (mode = = UV_RUN_ONCE) {

Uv__update_time (loop)

Uv__run_timers (loop)

}

R = uv__loop_alive (loop)

/ / execute only once and exit the loop. UV_RUN_NOWAIT means there will be no blocking in the poll io phase and the loop will only be executed once.

If (mode = = UV_RUN_ONCE | | mode = = UV_RUN_NOWAIT)

Break

}

/ / it is because uv_stop is called to exit, reset flag

If (loop- > stop_flag! = 0)

Loop- > stop_flag = 0

/ / returns whether there are any active tasks (handle or request). The business representative can perform uv_run again.

Return r

}

At this point, the study of "what is the logic of the implementation of the Libuv event loop" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report