三、TCP/UDP
Libuv最常用的应用是TCP和UDP通信。它们是libuv的主要功能,但有很多文章都描述了,本文就不涉及了。
四、人工通知事件
一般情况下,一个线程运行一个事件循环,线程阻塞,等待事件的发生,如果我们想“干预”一下这个事件循环,例如,停止它,向某个socket通道发点信息等,就需要人工“制造”一个消息触发一次,此时就需要用到uv_async_t。由于事件循环的线程处于阻塞状况,所以发消息的函数应该在另一个线程。下面是一个示例。
int test_async()
{
int res;
uv_loop_t* loop = uv_default_loop();
auto async_cb = [](uv_async_t* handle)
{
printf("stop loop now\n");
uv_stop(uv_handle_get_loop((uv_handle_t *)handle));
};
uv_async_t hasync;
if (res = uv_async_init(loop, &hasync, async_cb); res)
{
fprintf(stderr, "uv_async_init error %s\n", uv_strerror(res));
return -1;
}
std::thread otherthread([](uv_async_t* p) {
std::this_thread::sleep_for(std::chrono::seconds(5));
uv_async_send(p);
}, &hasync);
uv_timer_t htimer;
if (res = uv_timer_init(loop, &htimer); res)
{
fprintf(stderr, "uv_timer_init error %s\n", uv_strerror(res));
return -2;
}
auto timer_cb = [](uv_timer_t* handle)
{
uint64_t timestamp = uv_hrtime();
printf("timer time out at [%I64u ms]\n",(timestamp / 1000000) % 100000);
};
res = uv_timer_start(&htimer, timer_cb, 0, 1000);
res = uv_run(loop, UV_RUN_DEFAULT);
uv_close((uv_handle_t*)& hasync, NULL);
uv_close((uv_handle_t*)& htimer, NULL); //uv_close must be called to avoid memory leakage
otherthread.join();
printf("end of loop\n");
return res;
}
此例中,有一个定时器,每秒触发一次,无限循环下去,但设置了一个人工事件,在另一个线程5秒之后通知这个线程触发,在事件中停止事件循环,整个程序结束。屏幕输出如下所示。
需要注意的是,除创建线程