loop对象
libev监视器介绍:libev监视器用法-CSDN博客
libev loop对象介绍:loop对象-CSDN博客
libev API吐血整理:https://download.csdn.net/download/qq_39466755/90794251
类似于日志记录器,可以同时存在多个事件循环(loop对象)从而避免多个循环发生冲突
示例:
// 示例1:向默认循环添加定时器
ev_timer timer_watcher;
ev_timer_init(&timer_watcher, callback, 2.0, 0.);
ev_timer_start(EV_DEFAULT, &timer_watcher); // 使用 EV_DEFAULT 宏// 示例2:操作自定义循环
struct ev_loop *custom_loop = ev_loop_new(0);
ev_io io_watcher;
ev_io_init(&io_watcher, io_cb, fd, EV_READ);
ev_io_start(custom_loop, &io_watcher); // 显式指定 custom_loop
loop的应用
单loop对象
单事件循环的多事件能力,一个 loop 实例可以同时处理以下多种事件监视器:
ev_io // I/O 事件(如套接字可读/可写)
ev_timer // 定时器事件
ev_signal // 信号事件
ev_periodic // 绝对时间或复杂周期事件
ev_idle // 空闲事件
ev_prepare // 循环准备事件
ev_check // 循环检查事件
// ... 其他类型
这些监视器循环监视,但是每个事件又是驱动事件处理;
多个loop对象
每个事件都能独立循环监听
// 线程1:默认循环
void* thread1(void* arg) {ev_run(EV_DEFAULT, 0);return NULL;
}// 线程2:自定义循环
void* thread2(void* arg) {struct ev_loop *loop2 = ev_loop_new(0);ev_run(loop2, 0);ev_loop_destroy(loop2);return NULL;
}//错误示例:
// ❌ 错误示例:第二个 ev_run 永远不会被执行
struct ev_loop *loop1 = EV_DEFAULT;
struct ev_loop *loop2 = ev_loop_new(0);ev_run(loop1, 0); // 阻塞在此,直到 loop1 停止
ev_run(loop2, 0); // 永远不会到达这里!
ev_loop_destroy(loop2);//当然也可以设置成无阻塞
// 单线程中交替处理两个循环(不推荐常规使用)
while (true) {ev_run(loop1, EVRUN_NOWAIT); // 非阻塞模式处理一次 loop1ev_run(loop2, EVRUN_NOWAIT); // 非阻塞模式处理一次 loop2
}
标志位
ev_default_loop和ev_loop_new的标志位
enum {/* the default */EVFLAG_AUTO = 0x00000000U, /*默认行为,不启用任何特殊标志。*//* flag bits */EVFLAG_NOENV = 0x01000000U, /* 禁止从环境变量读取配置(默认情况下,libev 会检查 LIBEV_FLAGS 等环境变量来配置事件循环) */EVFLAG_FORKCHECK = 0x02000000U, /* 每次事件循环迭代时检查进程是否 fork 过(如果进程调用了 fork(),事件循环可能失效。启用此标志后,libev 会主动检测并自动重建内部状态(但性能略有损耗)。) *//* debugging/feature disable */EVFLAG_NOINOTIFY = 0x00100000U, /* 禁用 inotify 文件监控机制(仅影响文件描述符监控相关功能,) */
#if EV_COMPAT3EVFLAG_NOSIGFD = 0, /* 废弃 */
#endifEVFLAG_SIGNALFD = 0x00200000U, /* 尝试使用 signalfd 处理信号(Linux 特有机制,通过 signalfd 将信号转为文件描述符事件,避免信号处理函数的异步风险。若系统不支持,则自动回退到传统方式。) */EVFLAG_NOSIGMASK = 0x00400000U, /* 避免修改进程的信号掩码(signal mask),默认情况下,libev 会阻塞信号以避免竞态条件。此标志禁止此行为,适用于信号已由其他代码管理的场景。 */EVFLAG_NOTIMERFD = 0x00800000U /* 禁用 timerfd 定时器机制(Linux 特有) 强制使用传统定时器(如 setitimer),兼容旧系统或避免 timerfd 的某些问题*/
};
按位或组合的标志
EVBACKEND_SELECT 0x00000001U select //几乎全平台支持,但性能差(O(n) 时间复杂度)。
EVBACKEND_POLL 0x00000002U poll //多数 Unix 系统支持(Windows 和 AIX 除外),在 macOS 上有缺陷。
EVBACKEND_EPOLL 0x00000004U epoll //Linux 专属高性能后端(O(1) 时间复杂度)。
EVBACKEND_KQUEUE 0x00000008U kqueue //BSD 系列(FreeBSD/OpenBSD/macOS),但 macOS 实现存在已知问题。
EVBACKEND_DEVPOLL 0x00000010U /dev/poll //Solaris 8 的专有机制(libev 未完全实现)。
EVBACKEND_PORT 0x00000020U Event Ports //Solaris 10+ 的高效后端。
EVBACKEND_LINUXAIO 0x00000040U Linux AIO //Linux 4.19+ 的异步 I/O 接口(需内核支持)。
EVBACKEND_IOURING 0x00000080U io_uring //Linux 5.1+ 的现代异步 I/O 框架(高性能,支持批量操作)。
EVBACKEND_ALL 0x000000FFU 所有已知后端 //编译时启用 libev 支持的所有后端。
EVBACKEND_MASK 0x0000FFFFU 未来兼容掩码 //保留位,用于支持未来可能新增的后端。