close 异常

2022-11-08 11:22:33 +08:00
 lestly

非阻塞 socket ,执行请求超时后,就会被 close 掉。但是通过 ls -l /proc/pid/fd 看到,原本的 socket 变成了 pipe ,而且一直占用着这个句柄无法使用。另外写了检测程序,再次 close 才能把这个 pipe 删掉。这是为什么呢?

1553 次点击
所在节点    Linux
11 条回复
ho121
2022-11-08 12:00:19 +08:00
leonshaw
2022-11-08 13:23:17 +08:00
socket 怎么会变成 pipe ?程序又打开了什么东西?
ihciah
2022-11-08 13:59:38 +08:00
fd 号会重用的,旧的 fd 关了再打开新的,可能是同一个 fd 号。
lestly
2022-11-08 14:15:12 +08:00
@ho121 netstat 检查了,不是 TIME_WAIT
lestly
2022-11-08 14:16:57 +08:00
@leonshaw 应该没有,程序只运行了很少模块。
lestly
2022-11-08 14:18:12 +08:00
@ihciah 句柄是同一个 iNode ,只不过 ls -l 后原本描述的 socket 变成 pipe ,并且程序再也无法使用这个句柄
ihciah
2022-11-08 14:41:20 +08:00
@lestly 你的 socket 有遵循 RAII 吗?如果它 close 了那么就不应当有人继续持有它。handler 本质上就是存一个 fd 数字,如果 fd 关了但你还持有,那么要么是引用到了不存在的 fd ,要么是引用到了之后打开的 fd 。
我猜一个 fix 是把你的 close 行为改成 shutdown writehalf ,这样 socket fd 仍旧是有效的;然后在 socket 对象析构时去做 fd close 。
leonshaw
2022-11-08 14:47:51 +08:00
@lestly strace 看看
lestly
2022-11-08 15:00:25 +08:00
@ihciah 多谢,我试试
lestly
2022-11-08 15:00:45 +08:00
lestly
2022-11-08 15:43:45 +08:00
@ihciah 我的实现是这样的 A 线程创建 socket ,添加链表到 B 线程负责网络处理,我想这样应该不会引起多线程的占用 socket 的问题。我刚试了下,请求结束后,关闭连接时先 shutdown ,在 close ,还是会出现句柄释放不成功。
这是我在 /proc/pid/fd ls -l 操作的结果
lrwx------ 1 lestly lestly 64 11 月 8 15:25 10 -> 'socket:[208718]'
close 后变成
lr-x------ 1 lestly lestly 64 11 月 8 15:25 10 -> 'pipe:[208751]'

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/893529

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX