我的多线程网络服务器程序有问题。
我有一个主线程正在侦听新的客户端连接。我使用 Linux epoll 来获取 I/O 事件通知。对于每个传入事件,我创建一个接受()新连接并为其分配 fd 的线程。在重负载下,可能会发生相同的 fd 被分配两次导致我的程序崩溃的情况。
我的问题是:系统如何重新分配另一个线程仍在使用的 fd?
谢谢,
我的多线程网络服务器程序有问题。
我有一个主线程正在侦听新的客户端连接。我使用 Linux epoll 来获取 I/O 事件通知。对于每个传入事件,我创建一个接受()新连接并为其分配 fd 的线程。在重负载下,可能会发生相同的 fd 被分配两次导致我的程序崩溃的情况。
我的问题是:系统如何重新分配另一个线程仍在使用的 fd?
谢谢,
大概这里有一个竞争条件 - 但没有看到你的代码很难诊断。
您最好accept
在主线程上,然后将接受的套接字传递给新线程。
如果您将侦听套接字传递给新线程然后执行接受 - 您将遇到竞争条件。
有关更多信息,您可以在这里查看:https ://stackoverflow.com/a/4687952/516138
这是网络效率的一个很好的背景(虽然可能有点过时)。
您应该在您正在调用的同一线程上调用 accept() epoll()
。否则,您正在邀请比赛条件。
文件描述符以“每个进程为基础”进行修改。这意味着它们对于每个过程都是唯一的。这意味着多个线程可以在同一个进程中共享相同的文件描述符。
让accept
系统调用在同一进程中返回相同的文件描述符是一个非常强烈的迹象,表明您的某些线程正在关闭重复文件描述符的先前“版本”。
像这样的问题在复杂的软件中可能很难调试。在 Linux 系统中识别它的一种方法是使用strace
命令。一个可以跑strace -f -e trace=close,accept4,accept,pipe,open <your program>
。这将在您的屏幕上输出命令中指定的相应系统调用以及调用它的线程。