Libuv可用的工具集合

来源:互联网 发布:女子防身知乎 编辑:程序博客网 时间:2024/06/05 08:52

Libuv可用的工具集合

文章目录
  • 定时器(Timers)
  • 事件循环引用计数(Event loop reference count)
  • 空闲监视器模式(Idle watcher pattern)
  • 向工作者线程传递数据(Passing data to worker thread)
  • 轮询方式下的外部 I/O(External I/O with polling)
  • 检查并预备监视器(Check & Prepare watchers)
  • 库的加载(Loading libraries)
  • TTY

This chapter catalogues tools and techniques which are useful for common tasks. Thelibev 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)

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 optionalrepeat. 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 ofuv_timer_start, then repeats every 2 seconds (the repeat). Use:

uv_timer_stop(&timer_req);

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 initialtimeout and repeat set to the old repeat value. If the timer hasn’t been started it fails (error codeUV_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 thenuv_run will still exit.

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

ref-timer/main.c

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

0 0
原创粉丝点击