2016-02-24 5 views
0

я подумал, если бы я не назвал ev_loop_fork в ребенке, то наблюдатель в ребенке не будет срабатывать., что случилось, если я не звонил ev_loop_fork в ребенке

Это мой код, я строю ev_loop с EVBACKEND_EPOLL и EVFLAG_NOENV флаги.

Так нет EVFLAG_FORKCHECK флаг.

Тогда я прокомментирую ev_loop_fork вызов ребенка.

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

Но на самом деле, выход что-то вроде этого:

$ 4980 вилы 4981

$ тайм-аут в 4980

$ времени на 4981

, казалось что наблюдатели все еще были вызваны у ребенка, он вел себя так же, как и вызов ev_loop_fork.

Так в чем же проблема, спасибо.

#include<ev.h> 
#include<stdio.h> 
#include<unistd.h> 

void timeout_cb(EV_P_ ev_timer *w,int revents) 
{ 
    printf("time out at %d\n", getpid()); 
    ev_break(EV_A_ EVBREAK_ONE); 
} 

int main() 
{ 
    int ret; 
    ev_timer timeout_watcher; 

    struct ev_loop *loop = ev_default_loop(EVBACKEND_EPOLL | EVFLAG_NOENV); 

    ev_timer_init(&timeout_watcher,timeout_cb,5.5,0.); 
    ev_timer_start(loop,&timeout_watcher); 
    ret = fork(); 
    if(ret>0) printf("%d fork %d\n",getpid(),ret); 
    else if(ret==0) 
    { 
     //ev_loop_fork(EV_DEFAULT); 
    } 
    else return -1; 
    ev_run(loop,0); 
    return 0; 
} 

ответ

0

В руководстве libev не говорится, что после вилки цикл события будет остановлен. Все, что он говорит, это то, что, чтобы убедиться, что цикл события будет правильно работать с дочерью, вам нужно вызвать ev_loop_fork(). То, что на самом деле происходит, зависит от бэкэнда.

И технически таймеры будут даже более устойчивы к вилкам в большинстве бэкендов: select(), poll(), epoll(), kqueue all позволяют специфицировать значение таймаута, после которого эти функции возвращаются в случае отсутствия события , libev использует эту функцию, чтобы иметь возможность запускать таймауты, когда они должны запускаться. Поэтому нет необходимости перерегистрировать любые файловые дескрипторы для работы тайм-аутов.