0

在 libev 中,我已经初始化了 io watcher 以捕获事件,并且该事件导致将某些值存储在某个缓存中。我有另一个计时器观察器,它每 10 秒运行一次,读取缓存值。在这种情况下,我认为存在竞争条件。我需要在两个不同的 libev watcher 中使用 lock 还是 libev 处理它。

例如:

 TCP_CACHE_TIMEOUT = g_hash_table_new_full(g_str_hash, g_int_equal, key_destroy_cb, value_destroy_timeoutcb);
    zlog_info(_c,"TCP Server started at _port: %d",_port);
    int fd =setup_tcp_socket(_port);
    if(fd<0)
    {
        return NULL;
    }

    struct ev_loop *loop = EV_DEFAULT;

    struct _sock_ev_serv server;
    server.fd = fd;
    ev_io_init(&server.io, event_server, server.fd, EV_READ);
    ev_io_start(EV_A_ &server.io);

    ev_timer_init (&timeout_watcher, timeout_idle_fd, 0, 10.);
    ev_timer_again (loop,&timeout_watcher);

    ev_loop(loop, 0);  

在这里,我有循环并初始化 io watcher 以接受服务器事件,并且 timer watcher 每 10 秒查看一次缓存。在这种情况下,我是否需要自己处理比赛条件,或者两个观察者 io 和计时器运行时间由 libev 管理?

4

1 回答 1

1

简短的回答:没有竞争条件,你不需要锁。

更长的答案:
没有竞争条件的原因是因为 libev 在循环中检查 io 观察程序,然后是计时器,然后是 io,然后是计时器......
无论哪个先触发,都会先运行。两个回调之间没有重叠。

但是,如果您使用的是线程事件循环(可能,但根据您的代码判断不太可能),并且您在两个不同的线程中从同一个文件中读取,那么就会出现竞争条件并且您需要锁定。

示例:
如果您在 0.9 秒后在 io watcher 中获取数据,并且该 watcher 的回调需要 0.2 秒运行,则您的计时器将在 io 回调完成后调用(大约 10.1 秒)。

于 2016-02-11T22:56:15.463 回答