accept()在信号和epoll_wait()上中断

如果我是监听套接字上的epoll_wait(),当epoll_wait()返回表明它有活动时(在这种情况下,等待接受()ed的连接),那么如果accept()调用失败并且errno = EINTR ,epoll_wait()是否表示下一次返回时,同一连接正在侦听套接字上等待?

即,我是否需要做以下事情:

while(1){
    epoll_wait(epfd, &events, maxevents, timeout);
    if (events.data.fd == listener){
        connsock = accept(listener, &addr, &addrlen);
        while (connsock != -1){
            if (errno == EINTR){
                accept(listener, &addr, &addrlen);
                }
            }
        }
    }

为了确保连接被接受,或者这将工作并仍然确保接受的信号中断了accept()的连接:

while(1){
    epoll_wait(epfd, &events, maxevents, timeout);
    if (events.data.fd == listener){
        connsock = accept(listener, &addr, &addrlen);
        }
    }

在这种情况下,如果accept()被一个信号中断,那么在epoll_wait再次返回之后,它将在下一次循环时获取相同的连接.

显然,在这两个例子中我都做了一些假设(例如,在给定的epoll_wait调用中只返回一个套接字上的一个事件)并且不进行错误检查(除了在accept()上的EINTR,因为它是整个点这里)简化事情

最佳答案 这是边沿触发和电平触发之间的差异.使用级别触发,默认情况下,您不必担心它.

与级别触发的权衡是,您不能让一个线程处理检测到的事件,而另一个线程返回调用epoll_wait – 它只会再次检测到同一事件.但在大多数情况下,无论如何你都不需要这样做,并且不可能失去一个事件的权衡是值得的.

点赞