libuv 安装
1. 安装
环境如下:
- Ubuntu Server 24.04 LTS
安装步骤如下:
1 | |
2. 将 libuv 集成到 CMake
1 | |
3. 开发注意事项
3.1 uv_default_loop()
libuv 是基于事件驱动的。所有的网络读写、定时器等操作都需要挂载到一个事件循环(Event Loop)上。使用此函数获取系统的默认事件循环实例,并赋值给全局或静态变量;
3.2 uv_udp_bind(..., ..., UV_UDP_REUSEADDR)
UV_UDP_REUSEADDR 这个标志位告诉操作系统开启端口复用。这在开发和生产环境中非常重要:如果程序崩溃或重启,端口通常会处于 TIME_WAIT 等状态被系统保留一段时间。开启此选项可以允许程序立即再次绑定该端口,避免端口已被占用的错误;
3.3 uv_run(loop, UV_RUN_DEFAULT)
这是一个阻塞型函数,是启动整个事件循环的马达。一旦调用,它就会在一个死循环中不断检查是否有网络事件、定时器事件发生,直到没有任何活动的句柄为止。通常的做法是在主线程完成所有模块的初始化后,再拉起一个专门的线程去执行 uv_run();
当把 uv_run() 放到了独立的后台线程中,架构就变成了多线程环境。这个时候必须遵守 libuv 最重要的一条铁律:
libuv 的事件循环和它上面的所有句柄都是非线程安全的!
这意味着绝对不能在主线程(或者其他工作线程)里直接调用 uv_udp_send() 向外发数据,或者调用 uv_close() 关闭 socket;
跨线程通信:
如果需要在主线程触发网络层发送数据,必须使用 libuv 提供的唯一线程安全机制:uv_async_t。它的工作原理是:
在初始化阶段,向事件循环注册一个
uv_async_t句柄和一个回调函数;当主线程想要发送数据时,主线程将数据放入一个线程安全的队列(例如:加锁的链表),然后调用
uv_async_send(&async_handle);uv_async_send()会以线程安全的方式唤醒后台的事件循环线程;事件循环线程被唤醒后,会在自己的线程上下文中执行之前注册好的 async 回调函数。在这个回调函数里,再从队列中取出数据,并安全地调用
uv_udp_send();