0

libev で、イベントをキャッチするために io ウォッチャーを初期化しました。このイベントにより、特定の値がキャッシュに保存されます。10秒ごとに実行され、キャッシュ値を読み取る別のタイマーウォッチャーがあります。そのような場合、競合状態があると思います。2 つの異なる libev ウォッチャーでロックを使用する必要がありますか、または 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 ウォッチャーをループして初期化し、タイマー ウォッチャーを 10 秒ごとにキャッシュを調べるようにしています。このような場合、競合状態を自分で処理する必要がありますか、それとも 2 つのウォッチャー io とタイマーの実行時間は libev によって管理されますか?

4

1 に答える 1

1

簡単な答え: 競合状態はありません。ロックは必要ありません。

より長い答え:
競合状態がない理由は、libev が io ウォッチャー、タイマー、io、タイマーの順にチェックするループにあるためです
。最初にトリガーされた方が最初に実行されます。2 つのコールバックの間にオーバーラップはありません。

ただし、スレッド化されたイベント ループを使用していて (可能ですが、コードから判断する可能性は低い)、2 つの異なるスレッドで同じファイルから読み取っていた場合、競合状態が発生し、ロックが必要になります。

例:
0.9 秒後に io ウォッチャーでデータを取得し、そのウォッチャーのコールバックの実行に 0.2 秒かかる場合、タイマーは io コールバックが既に終了した後 (約 10.1 秒) に呼び出されます。

于 2016-02-11T22:56:15.463 に答える