libuv中的UV_RUN_NOWAIT模式是如何工作的? [英] How does the UV_RUN_NOWAIT mode work in libuv?

查看:454
本文介绍了libuv中的UV_RUN_NOWAIT模式是如何工作的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 uv_run 函数在 libuv 中运行事件循环时,有一个mode"参数与以下值一起使用:

When running an event loop in libuv using the uv_run function, there's a "mode" parameter that is used with the following values:

UV_RUN_DEFAULT
UV_RUN_ONCE
UV_RUN_NOWAIT

前两个是显而易见的.UV_RUN_DEFAULT 运行事件循环直到没有更多事件,并且 UV_RUN_ONCE 处理循环中的单个事件.但是,UV_RUN_NOWAIT 似乎不是一个单独的模式,而是一个可以与其他两个值之一进行 OR 运算的标志.

The first two are obvious. UV_RUN_DEFAULT runs the event loop until there are no more events, and UV_RUN_ONCE processing a single event from the loop. However, UV_RUN_NOWAIT doesn't seem to be a separate mode, but rather a flag that can be ORed with one of the other two values.

默认情况下,此函数会阻塞,直到事件处理完毕,并且 UV_RUN_NOWAIT 使它成为非阻塞的,但我能找到的任何文档都到此为止.我的问题是,如果您非阻塞地运行事件循环,回调是如何处理的?

By default, this function blocks until events are done processing, and UV_RUN_NOWAIT makes it nonblocking, but any documentation I can find on it ends there. My question is, if you run the event loop nonblocking, how are callbacks handled?

libuv 事件模型是单线程的(反应堆模式),所以我假设它需要阻塞才能调用回调,但是如果主线程被占用,事件处理后会发生什么?回调会被排队"直到 libuv 再次获得主线程的控制权吗?还是会在另一个线程上调度回调?

The libuv event model is single-threaded (reactor pattern), so I'd assume it needs to block to be able to call the callbacks, but if the main thread is occupied, what happens to an event after it's processed? Will the callback be "queued" until libuv gets control of the main thread again? Or will the callbacks be dispatched on another thread?

推荐答案

回调的处理方式相同.它们将在 uv_run() 中的线程内运行.

Callbacks are handled in the same manner. They will run within the thread that is in uv_run().

根据文档:

  • UV_RUN_DEFAULT:运行事件循环,直到引用计数降至零.总是返回零.
  • UV_RUN_ONCE:轮询一次新事件.请注意,如果没有未决事件,则此功能会阻塞.完成后返回零(没有活动句柄或请求剩余),或者如果预期有更多事件,则返回非零(意味着您应该在将来的某个时候再次运行事件循环).
  • UV_RUN_NOWAIT:轮询一次新事件,但如果没有未决事件则不阻塞.
  • UV_RUN_DEFAULT: Runs the event loop until the reference count drops to zero. Always returns zero.
  • UV_RUN_ONCE: Poll for new events once. Note that this function blocks if there are no pending events. Returns zero when done (no active handles or requests left), or non-zero if more events are expected (meaning you should run the event loop again sometime in the future).
  • UV_RUN_NOWAIT: Poll for new events once but don't block if there are no pending events.

考虑一个程序有一个监听套接字的观察者的情况.在这种情况下,当套接字接收到数据时将创建一个事件.

Consider the case where a program has a single watcher listening to a socket. In this scenario, an event would be created when the socket has received data.

  • UV_RUN_DEFAULT 即使套接字没有数据也会阻塞调用者.在以下任一情况下,调用者将从 uv_run() 返回:
    • 循环已通过uv_stop()
    • 没有更多的观察者在循环中运行.例如,唯一的观察者已停止.
    • UV_RUN_DEFAULT will block the caller even if the socket does not have data. The caller will return from uv_run(), when either:
      • The loop has been explicitly stopped, via uv_stop()
      • No more watchers are running in the loop. For example, the only watcher has been stopped.
      • 循环已通过uv_stop()
      • 没有更多的观察者在循环中运行.例如,唯一的观察者已停止.
      • 它最多处理了一个事件.比如socket收到数据,已经调用了用户回调.可能已准备好处理其他事件,但不会在当前 uv_run() 调用中处理.
      • The loop has been explicitly stopped, via uv_stop()
      • No more watchers are running in the loop. For example, the only watcher has been stopped.
      • It has handled a max of one event. For example, the socket received data, and the user callback has been invoked. Additional events may be ready to be handled, but will not be handled in the current uv_run() call.

      通常,以非阻塞方式运行事件循环是为了与其他事件循环集成.考虑一个具有两个事件循环的应用程序:用于后端工作的 libuv 和 Qt UI(由其自己的事件循环驱动).能够以非阻塞方式运行事件循环允许单个线程在两个事件循环上分派事件.这是一个简单的概述,显示了由单个线程处理的两个 libuv 循环:

      Often times, running an event-loop in a non-blocking manner is done to integrate with other event-loops. Consider an application that has two event loops: libuv for backend work and Qt UI (which is driven by its own event loop). Being able to run the event loop in a non-blocking manner allows for a single thread to dispatch events on both event-loops. Here is a simplistic overview showing two libuv loops being handled by a single thread:

      uv_loop_t *loop1 = uv_loop_new();
      uv_loop_t *loop2 = uv_loop_new();
      
      // create, initialize, and start a watcher for each loop.
      ...
      
      // Handle two event loops with a single thread.
      while (uv_run(loop1, UV_RUN_NOWAIT) || uv_run(loop2, UV_RUN_NOWAIT));
      

      如果不使用 UV_RUN_NOWAITloop2 只会运行一次 loop1loop1 的观察者被停止.

      Without using UV_RUN_NOWAIT, loop2 would only run once loop1 or loop1's watchers have been stopped.

      有关更多信息,请考虑阅读高级事件循环进程部分libuv简介.

      For more information, consider reading the Advanced Event Loops and Processes sections of An Introduction to libuv.

      这篇关于libuv中的UV_RUN_NOWAIT模式是如何工作的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆