非阻塞 socket ,执行请求超时后,就会被 close 掉。但是通过 ls -l /proc/pid/fd 看到,原本的 socket 变成了 pipe ,而且一直占用着这个句柄无法使用。另外写了检测程序,再次 close 才能把这个 pipe 删掉。这是为什么呢?
1
ho121 2022-11-08 12:00:19 +08:00
|
2
leonshaw 2022-11-08 13:23:17 +08:00
socket 怎么会变成 pipe ?程序又打开了什么东西?
|
3
ihciah 2022-11-08 13:59:38 +08:00 via iPhone
fd 号会重用的,旧的 fd 关了再打开新的,可能是同一个 fd 号。
|
6
lestly OP @ihciah 句柄是同一个 iNode ,只不过 ls -l 后原本描述的 socket 变成 pipe ,并且程序再也无法使用这个句柄
|
7
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 。 |
11
lestly OP @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]' |