3

使用 epoll_wait 来管理使用多个线程的多个连接,尝试释放与关闭的套接字关联的自定义数据存在风险。

考虑以下场景,其中 T 是自定义数据:

  1. 收到数据,
  2. 因为1,线程A从epoll_wait解除阻塞,处理事件(访问T)
  3. 同时,另一个线程B,想要关闭连接

线程 B 不能假设 T 可以安全地删除,即使调用 close 会立即从 epoll 中删除套接字。

我有以下标准想法:

在 T 中维护一个变量,该变量在每次调用 write/read 返回 EAGAIN 时递增,并在每次套接字准备好时递减。调用 close 时,在删除 T 之前等待该变量降至零。我遇到的问题是,如果调用 close,epoll_wait 不会返回取消先前调用以武装套接字的指示。

有人有同样的问题吗?你是如何克服它的?

4

2 回答 2

4

这里至少有三种可能的方式:

  • 不要使用线程,简单干净,通常可以工作。

  • 让一个专用线程执行所有文件描述符轮询并将事件发布到执行实际 I/O 和处理的工作线程池。

  • 每个线程有一个epoll(7)实例,因此线程管理不相交的描述符集,除了监听套接字来填充这些集,以及一些控制机制,如eventfd(2), 或 self-pipe(2)能够关闭整个钻机干净地。

希望这可以帮助。

于 2012-12-10T21:08:52.663 回答
1

After many research, I found this recent and remarkable article : http://lwn.net/Articles/520012/ Basically it acknowledge the issue I am describing and speaks about a possible future patch to Linux kernel that allows to extend the epoll API in a way that solves the issue.

The extension bring a new command called : EPOLL_CTL_DISABLE. When it is issued, and by means of return value, the calling thread will know if some other thread has just been deblocked from epoll_wait upon same socket. This can help know the safe moment of closure and release of custom data.

于 2012-12-12T22:06:00.737 回答