POSIX及Windows系统下父子进程closesocket调用规则问询
结论
Windows下的套接字资源管理逻辑和POSIX系统是一致的:每个持有套接字副本的进程,都需要在使用完后单独调用closesocket,不能只在单个进程(比如父进程)里调用一次就完事。
具体说明
- POSIX系统中
fork操作会让套接字fd的引用计数+1,每次close操作计数-1,直到计数归零内核才会释放套接字资源,这个逻辑你已经了解。 - Windows环境下,不管是通过子进程继承得到的套接字句柄,还是通过
WSADuplicateSocketA机制复制得到的跨进程套接字,底层都是用引用计数管理的:- 每多一个进程持有同一个底层套接字的句柄,引用计数就会加1
- 单个进程调用
closesocket只会释放当前进程持有的这个句柄实例,同时把引用计数减1 - 只有当所有持有句柄的进程都调用了
closesocket,引用计数降到0时,底层的套接字资源才会被系统真正释放
- Winsock官方文档也明确验证了这个规则:
进程可对复制得到的套接字调用closesocket,对应的描述符会被释放。但底层套接字会保持打开状态,直到最后一个剩余的描述符调用closesocket后才会关闭。
注意事项
就算你忽略套接字句柄继承带来的各类潜在兼容问题,坚持使用跨进程共享套接字的机制,也必须保证每个持有句柄的进程在使用完毕后都调用closesocket,否则会出现套接字资源泄漏,甚至TCP连接无法正常四次挥手关闭的问题。
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

