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

时间:2013-06-12 09:24:43

标签: c++ c multithreading networking epoll

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

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

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

谢谢,

3 个答案:

答案 0 :(得分:3)

据推测,这里存在竞争条件 - 但是没有看到你的代码就很难诊断出来。

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

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

有关详细信息,请参阅此处:https://stackoverflow.com/a/4687952/516138

this是网络效率的良好背景(虽然可能有点过时)。

答案 1 :(得分:0)

您应该在调用epoll()的同一个线程上调用accept()。否则你会邀请竞争条件。

答案 2 :(得分:0)

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

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

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