блокировка io watcher и timer watch в libev

в libev я инициализировал наблюдателя ввода-вывода для перехвата событий, и это событие приводит к сохранению определенного значения в некотором кеше. У меня есть еще один наблюдатель за таймером, который запускается каждые 10 секунд, считывает значение кеша. В таком случае я полагаю, что есть состояние гонки. мне нужно использовать блокировку в двух разных наблюдателях libev или libev справится с этим.

eg:

 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 секунд. В таком случае нужно ли мне самому обрабатывать состояние гонки, или время работы двух наблюдателей и таймера управляется libev?


person user5335302    schedule 15.01.2016    source источник


Ответы (1)


Краткий ответ: нет условий гонки, вам не нужна блокировка.

Более длинный ответ:
Причина отсутствия состояния гонки заключается в том, что libev находится в цикле, проверяющем наблюдателя ввода-вывода, затем таймер, затем ввод-вывод, затем таймер.....
Какой бы ни был срабатывает первым, запускается первым. Между двумя обратными вызовами нет перекрытия.

Однако, если вы используете многопоточный цикл обработки событий (возможно, но маловероятно, судя по вашему коду) и читаете из одного и того же файла в двух разных потоках, тогда возникнет состояние гонки и вам потребуется блокировка.

Пример:
Если вы получаете данные в наблюдателе ввода-вывода через 0,9 секунды, а ваш обратный вызов для этого наблюдателя занимает 0,2 секунды, ваш таймер будет запущен после того, как обратный вызов ввода-вывода уже завершится (примерно через 10,1 секунды).

person Community    schedule 11.02.2016