转载 2016年08月31日 16:39:46



This chapter catalogues tools and techniques which are useful for common tasks. The libev man page already covers some patterns which can be adopted to libuv through simple API changes. It also covers parts of the libuv API that don’t require entire chapters dedicated to them.


Timers invoke the callback after a certain time has elapsed since the timer was started. libuv timers can also be set to invoke at regular intervals instead of just once.

Simple use is to init a watcher and start it with a timeout, and optional repeat. Timers can be stopped at any time.

uv_timer_t timer_req;

uv_timer_init(loop, &timer_req);
uv_timer_start(&timer_req, callback, 5000, 2000);

will start a repeating timer, which first starts 5 seconds (the timeout) after the execution of uv_timer_start, then repeats every 2 seconds (the repeat). Use:


to stop the timer. This can be used safely from within the callback as well.

The repeat interval can be modified at any time with:

uv_timer_set_repeat(uv_timer_t *timer, int64_t repeat);

which will take effect when possible. If this function is called from a timer callback, it means:

  • If the timer was non-repeating, the timer has already been stopped. Use uv_timer_start again.
  • If the timer is repeating, the next timeout has already been scheduled, so the old repeat interval will be used once more before the timer switches to the new interval.

The utility function:

int uv_timer_again(uv_timer_t *)

applies only to repeating timers and is equivalent to stopping the timer and then starting it with both initial timeout and repeat set to the old repeat value. If the timer hasn’t been started it fails (error code UV_EINVAL) and returns -1.

An actual timer example is in the reference count section.

事件循环引用计数(Event loop reference count)

The event loop only runs as long as there are active watchers. This system works by having every watcher increase the reference count of the event loop when it is started and decreasing the reference count when stopped. It is also possible to manually change the reference count of handles using:

void uv_ref(uv_handle_t*);
void uv_unref(uv_handle_t*);

These functions can be used to allow a loop to exit even when a watcher is active or to use custom objects to keep the loop alive.

The former can be used with interval timers. You might have a garbage collector which runs every X seconds, or your network service might send a heartbeat to others periodically, but you don’t want to have to stop them along all clean exit paths or error scenarios. Or you want the program to exit when all your other watchers are done. In that case just unref the timer immediately after creation so that if it is the only watcher running then uv_run will still exit.

The later is used in node.js where some libuv methods are being bubbled up to the JS API. A uv_handle_t (the superclass of all watchers) is created per JS object and can be ref/unrefed.


uv_loop_t *loop;
uv_timer_t gc_req;
uv_timer_t fake_job_req;

int main() {
    loop = uv_default_loop();

    uv_timer_init(loop, &gc_req);
    uv_unref((uv_handle_t*) &gc_req);

    uv_timer_start(&gc_req, gc, 0, 2000);

    // could actually be a TCP download or something
    uv_timer_init(loop, &fake_job_req);
    uv_timer_start(&fake_job_req, fake_job, 9000, 0);
    return uv_run(loop, UV_RUN_DEFAULT);

We initialize the garbage collector timer, then immediately unref it. Observe how after 9 seconds, when the fake job is done, the program automatically exits, even though the garbage collector is still running.

空闲监视器模式(Idle watcher pattern)

The callbacks of idle watchers are only invoked when the event loop has no other pending events. In such a situation they are invoked once every iteration of the loop. The idle callback can be used to perform some very low priority activity. For example, you could dispatch a summary of the daily application performance to the developers for analysis during periods of idleness, or use the application’s CPU time to perform SETI calculations


  • wangcg123
  • wangcg123
  • 2016年08月31日 16:31
  • 855


我们都知道libuv是异步非阻塞的,那么它究竟是如何实现异步的呢? Libuv中文编程指南上如是说 libuv提供的文件操作和 socket operations 并不相同. 套接字操作使用...
  • baidu20008
  • baidu20008
  • 2014年10月15日 17:27
  • 2329


  • ciaolemeng
  • ciaolemeng
  • 2017年08月24日 19:37
  • 475

libuv入门之hello world

先声明一下我的工作主目录为:/data/workspace/nodejs/learn_nodejs/node_modules/libuv, 在后面我会简称为$PATH。 第一步,编写代码 在$PA...
  • limite_god
  • limite_god
  • 2015年02月06日 15:40
  • 1275


  • js_gary
  • js_gary
  • 2017年05月16日 16:52
  • 925

关于网络通信模型的剖析:libevent libev libuv asio

libevent libev libuv node.js   工具库和框架之间的区别,asio是被设计成一套工具库而不是框架。 什么是框架? 框架就是一套固定了编程结构的库,任何用户使用它...
  • tgxallen
  • tgxallen
  • 2017年05月02日 17:10
  • 1767


  • wangcg123
  • wangcg123
  • 2016年08月31日 16:37
  • 1765


  • ad88282284
  • ad88282284
  • 2015年01月26日 14:30
  • 687


libuv库学习笔记(一) 文档翻译
  • paohui0134
  • paohui0134
  • 2016年06月11日 15:14
  • 1095


libuv的uv_queue_work 使用,不能在fork的子进程中使用,原因未调查清楚,记录一下! 望有清楚的提点一下,谢谢...
  • wangcg123
  • wangcg123
  • 2016年08月31日 16:13
  • 1813