进程退出时,Windows是否负责关闭套接字?


Answers:


10

在Windows和Unixen上,当进程退出时,内核都会关闭所有打开的句柄。

Windows NT

终止流程 – MSDN

终止进程具有以下结果:

  • [...]
  • 该进程分配的所有资源都将被释放。
  • 所有内核对象均已关闭。
  • [...]

当进程终止时,将自动关闭内核对象的打开句柄,而对象本身将一直存在,直到关闭它们的所有打开句柄为止。因此,如果另一个进程具有打开的句柄,则在使用该对象的进程终止后该对象将保持有效。

ExitProcess功能 – MSDN

退出进程将导致以下情况:

  • [...]
  • 进程打开的所有对象句柄均已关闭。
  • [...]

的Linux

exit(3) – Linux程序员手册(libc函数)

所有打开的stdio(3)流都将被刷新并关闭。

_exit(2) – Linux程序员手册(内核系统调用)

该功能_exit()“立即”终止调用过程。属于该进程的所有打开文件描述符都将关闭;进程1,init继承了该进程的所有子级,并且向该进程的父级发送SIGCHLD信号。


请注意,在两个操作系统上,

  1. 套接字只是文件描述符(fd)/内核对象的一种类型,因此上述内容同样适用于文件和套接字。

  2. Unix上的文件描述以及Windows上的对象处理内核对象可以由多个进程拥有- 它们的句柄可以由子进程继承,甚至可以使用特殊的IPC函数来传递。

  3. 仅当指向文件或套接字的所有 fd都被销毁时,才会关闭文件或套接字。


2
TCP套接字由于其TIME_WAIT状态而属于特殊情况。例如,如果终止在TCP端口上侦听的应用程序,则通常无法立即绑定到同一端口。
haimg 2012年

2
否。文件描述符和对象句柄仅由一个进程拥有,并且只能由一个进程访问,并且严格地是按进程的实体。在进程之间共享的是文件描述和基础对象。
JdeBP

5

在Windows上,套接字是通信端点和进程之间的链接。这就是为什么当您复制一个套接字时,最终只有两个端点,而只有一个端点。这就是为什么如果不在另一个进程中创建新的套接字就无法将套接字从一个进程传递到另一个进程的原因。

如果该进程不存在,则其套接字必然不存在。没有插座的过程,没有保持它的过程。这就是为什么即使是希望在内核级别创建套接字的Windows内核驱动程序也必须指定一个进程来拥有该套接字,或者从可以拥有该套接字的进程上下文中调用该函数。(或者他们可以不使用套接字而直接操纵端点。)

您的问题似乎实际上与套接字无关,而与通信端点本身有关。套接字引用了它的通信端点。当插座消失时,参考计数下降。如果达到零,则根据端点关联的通信协议的要求,将其尽快删除。TCP具有TIME_WAIT状态,在此状态下必须保留端点以处理任何“剩余”数据包。


3

是的,它确实。通过这种方式可以检测Windows 3.1 95 98 XP(至少从XP以来我肯定知道)。


1
不,还没有。从Windows NT版本3. 5开始,也许是。但是在套接字方面,DOS-Windows与Windows NT完全不同。而且,DOS-Windows 95与DOS-Windows 3.1明显不同。需要 Win16应用程序调用,WSACleanup()否则将发生泄漏;并且MSKB文章#156319中记录了DOS-Windows 9x中的一个令人讨厌的问题,父进程使传递给其子进程的套接字无效,这是由DOS-Windows套接字的完全不同的进程退出语义引起的。
JdeBP

1
@JdeBP:Windows NT 3怎么样?1-它执行自动清理了吗?
user1686

1
3.1首先没有套接字。
JdeBP 2012年

...好点,@ JdeBP-我没想到。
user1686

@JdeBP更新了答案以进行更正。
Scott Chamberlain 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.