epoll有线程安全问题吗?

时间:2013-01-09 15:01:45

标签: multithreading epoll

这是问题14221339的后续内容。

我有一个在epoll_wait()循环内运行的线程池。

外部线程调用epoll_ctl()并添加一个带

的侦听器套接字

(EPOLLET | EPOLLONESHOT | EPOLLIN)

当线程池只有一个线程时,它会间歇性地无法接收第一个(也是唯一的)连接尝试的EPOLLIN事件。如果我将线程池增加到两个,它几乎总是无法收到EPOLLIN事件。

我的理解是epoll API是线程安全的,但这种观察似乎表明不是这样。

1 个答案:

答案 0 :(得分:5)

使用边缘触发的语义,不正确的调用序列可能导致竞争条件。涉及三个系统调用:

  1. epoll_ctl()以激活通知(并重新激活if 使用了EPOLLONESHOT。
  2. epoll_wait()接收通知。
  3. 系统输入:循环中的read()/ recv()/ accept(),直到错误EAGAIN。
  4. 如果按此顺序执行(重复),则可以在#3和#1之间进行竞争:当内核中的输入事件发生在EAGAIN返回之后但在epoll_ctl()可以被执行之前。通常,重新激活需要在I / O之前完成。

    1. epoll_ctl()以激活通知(并重新激活if 使用了EPOLLONESHOT。
    2. 系统输入:循环中的read()/ recv()/ accept(),直到错误EAGAIN。
    3. epoll_wait()接收通知。
    4. (显然,I / O需要非阻塞。)