【发布时间】:2012-10-01 00:29:45
【问题描述】:
在对我编写的某些服务器代码进行压力测试时,我注意到即使我在描述符句柄上调用 close()(并验证结果是否有错误),描述符并未释放,最终导致 accept()返回错误“打开的文件太多”。
现在我明白这是因为 ulimit,我不明白为什么我在每个同步接受/读取/发送周期后调用 close() 时会点击它?
我正在通过使用 lsof 运行手表来验证描述符是否确实存在:
ctsvr 9733 mike 1017u sock 0,7 0t0 3323579 无法识别协议 ctsvr 9733 mike 1018u sock 0,7 0t0 3323581 无法识别协议 ...
果然有大约 1000 个左右。此外,使用 netstat 检查我可以看到没有挂起的 TCP 状态(没有 WAIT 或 STOPPED 或任何东西)。
如果我只是从客户端执行单个连接/发送/接收,我确实注意到套接字确实保留在 lsof 中;所以这甚至不是负载问题。
服务器在 Ubuntu Linux 64 位机器上运行。
有什么想法吗?
【问题讨论】:
-
假设你所说的一切都是真的,这听起来像是一个内核错误。成功关闭绝对必须释放描述符。
-
您是否在调用
shutdown和/或在关闭套接字句柄之前使用套接字中的所有数据?拨打close时,您是否挂了reads 或writes? -
尝试使用 strace,如果 connect/send/recv 调用像你说的那样紧密耦合,从诊断输出中应该很清楚
-
netstat --inet会告诉你 TCP 会话的状态。如果他们“成立”,你还没有打电话给close()。 -
如果您希望我们提供帮助,请发布一些代码。如果您无法这样做,请使用像 valgrind 这样的分析器来跟踪描述符。这对我来说听起来像是一个应用程序错误。