非阻塞 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]' |