You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 18:20:35