Unix accept()函数两次返回相同的文件描述符

unix accept() function returns the same file descriptor twice

本文关键字:文件 描述 两次 函数 accept Unix 返回      更新时间:2023-10-16

我的多线程网络服务器程序有问题。

我有一个主线程正在监听新的客户端连接。我使用Linux epoll来获取I/O事件通知。对于每个传入事件,我创建一个线程来接受()新连接并为其分配一个fd。在高负载情况下,可能会发生相同的fd被分配两次导致程序崩溃的情况。

我的问题是:系统如何重新分配一个仍然被另一个线程使用的fd ?

谢谢,

假设这里存在竞争条件-但如果没有看到您的代码,则很难诊断。

您最好在主线程上执行accept,然后将接受的套接字传递给新线程。

如果您将侦听套接字传递给一个新线程,然后执行接受-您将遇到竞争条件。

更多信息请访问:https://stackoverflow.com/a/4687952/516138

这是一个很好的关于网络效率的背景知识(尽管可能有点过时)。

您应该在调用epoll()的同一个线程上调用accept()。

文件描述符以"每个进程为基础"进行修改。这意味着它们对于每个进程都是唯一的。这意味着多个线程可以在同一进程中共享相同的文件描述符。

如果一个accept系统调用在同一个进程中返回相同的文件描述符,这是一个非常强烈的迹象,表明你的一些线程正在关闭重复文件描述符的上一个"版本"。

像这样的问题在复杂的软件中可能很难调试。在Linux系统中识别它的一种方法是使用strace命令。可以运行strace -f -e trace=close,accept4,accept,pipe,open <your program>。这将在屏幕上输出命令中指定的各自的系统调用以及调用它的线程。