Unix accept()函数两次返回相同的文件描述符
unix accept() function returns the same file descriptor twice
我的多线程网络服务器程序有问题。
我有一个主线程正在监听新的客户端连接。我使用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>
。这将在屏幕上输出命令中指定的各自的系统调用以及调用它的线程。
相关文章:
- 使用VerQueryValue检索应用程序的文件描述
- 如何在C/C++中用FD_set Unix设置套接字文件描述符
- I2C 文件描述符上的 I2C 总线可写/可读标志
- 许多文件描述符在调用sys_clone时
- AMQP-CPP >处理程序中的错误文件描述符
- 如何使用 WINAPI 和 C++ 提取可执行文件的文件描述?
- 正在等待在非阻塞文件描述符上长时间运行ioctl
- 有没有适用于Windows.lib文件的GNU二进制文件描述符(BFD)
- 如何强制文件描述符缓冲我的输出
- 如何从 boost::asio::ssl::stream<boost::asio::ip::tcp::socket> 获取本机套接字文件描述器?
- 哪个更适合从C++写入敏感的日志文件,在文件描述符上写()或文件上的fprintf()?
- 将 select() 与非基于文件描述符的输入一起使用
- accept(..) 似乎正在修改我给它的文件描述符参数
- 使用 Select 多路复用未命名的管道和其他文件描述符
- 提升 ASIO 绑定:错误的文件描述符
- 使用文件描述符移动对象
- 无法从零MQ ZMQ_SERVER套接字中获取文件描述符
- read() 上的不同行为取决于写入不可写内存时表示文件、匿名管道或套接字的文件描述符
- 我可以在不使用 FIOCANCEL 的情况下关闭 VxWorks 中的文件描述符吗?
- 将 Boost Asio 与 ZeroMQ 集成,文件描述符错误?