0

我想,如果我没有在 child 中调用ev_loop_fork,那么 child 中的 watcher 就不会被触发。

这是我的代码,我用EVBACKEND_EPOLLEVFLAG_NOENV标志构建了 ev_loop。

所以没有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;
}
4

1 回答 1

0

libev 手册并没有说在 fork 之后将停止事件循环。它只是说要确保事件循环在子进程中正常工作,您需要调用 ev_loop_fork()。实际发生的情况取决于后端。

从技术上讲,在大多数后端中,计时器甚至对分叉更有弹性:select()、poll()、epoll()、kqueue 都允许指定超时值,之后这些函数在没有事件的情况下返回。libev 使用此功能能够在应该触发超时时触发超时。因此,无需重新注册任何文件描述符即可使超时工作。

于 2016-06-22T00:14:18.277 回答