libevent事件定时器修改:释放事件后重设时间是否可行?
libevent定时器修改问题解答
原代码做法的正确性
你给出的代码可以正常运行,但并非最优实现:
- 每次定时器触发都销毁旧事件、创建新事件,会带来不必要的内存分配/释放开销,频繁触发时性能会受影响。
- 若
event是全局变量,多线程场景下容易出现竞态问题,比如在event_free后、新事件创建前,其他线程可能访问到无效的event指针。 - 必须确保
event_free后没有任何其他代码再引用该事件对象,否则会触发野指针错误。
单个事件实现定时器时间修改的方案
核心思路是复用已有事件对象,通过event_del移除现有超时,再用event_add设置新的超时时间,无需反复创建/销毁事件。
示例代码
#include <event2/event.h> struct event *g_timer_event = NULL; struct event_base *g_base = NULL; void timer_callback(evutil_socket_t fd, short events, void *arg) { // 处理定时器触发的业务逻辑 // ... // 修改定时器为300秒后触发 set_timer(300); } void set_timer(unsigned int seconds) { struct timeval tv = {seconds, 0}; if (g_timer_event) { // 先移除已注册的定时器事件 event_del(g_timer_event); } else { // 首次初始化事件(无需EV_PERSIST,因为我们手动重新设置超时) g_timer_event = event_new(g_base, -1, EV_TIMEOUT, timer_callback, NULL); if (!g_timer_event) { // 处理事件创建失败的逻辑,比如日志输出 return; } } // 添加新的超时时间 if (event_add(g_timer_event, &tv) != 0) { // 处理添加事件失败的逻辑 } }
关键注意事项
- 若使用
EV_PERSIST标记:触发后事件会自动以原超时时间重新注册,此时必须先调用event_del,再调用event_add设置新超时,否则无法修改时间。 - 事件对象的生命周期:确保在程序退出或不再需要定时器时,调用
event_free(g_timer_event)释放资源,避免内存泄漏。 - 多线程场景:对
g_timer_event的所有操作(event_del/event_add/event_free)需要加锁,避免并发访问导致的未定义行为。
内容的提问来源于stack exchange,提问作者IGP
相关产品推荐
相关产品推荐

