这是问题14221339的后续内容。
我有一个在epoll_wait()
循环内运行的线程池。
外部线程调用epoll_ctl()
并添加一个带
(EPOLLET | EPOLLONESHOT | EPOLLIN)
。
当线程池只有一个线程时,它会间歇性地无法接收第一个(也是唯一的)连接尝试的EPOLLIN
事件。如果我将线程池增加到两个,它几乎总是无法收到EPOLLIN
事件。
我的理解是epoll API是线程安全的,但这种观察似乎表明不是这样。
答案 0 :(得分:5)
使用边缘触发的语义,不正确的调用序列可能导致竞争条件。涉及三个系统调用:
如果按此顺序执行(重复),则可以在#3和#1之间进行竞争:当内核中的输入事件发生在EAGAIN返回之后但在epoll_ctl()可以被执行之前。通常,重新激活需要在I / O之前完成。
(显然,I / O需要非阻塞。)