我正在寻找Linux内核中处理进程死亡后的清理工作的地方。具体来说,我想查看它是否以及如何在使用-9信号杀死进程后处理打开的TCP连接。我相信它会关闭所有连接,但我想了解细节,并确定是否有任何可能连接没有正确关闭。
欢迎提供Linux内核源代码的指针。
我正在寻找Linux内核中处理进程死亡后的清理工作的地方。具体来说,我想查看它是否以及如何在使用-9信号杀死进程后处理打开的TCP连接。我相信它会关闭所有连接,但我想了解细节,并确定是否有任何可能连接没有正确关闭。
欢迎提供Linux内核源代码的指针。
进程终止的核心处理由exit.c:do_exit()
函数处理。该函数调用exit_files()
,后者再调用put_files_struct()
,最后调用close_files()
。
close_files()
循环遍历进程打开的所有文件描述符(包括所有套接字),对每个文件描述符调用filp_close()
,然后在struct file
对象上调用fput()
。当最后一个对struct file
的引用被释放时,fput()
会调用文件对象的.release()
方法,在套接字中,这是net/socket.c
中的sock_close()
函数。
我相信套接字的清理更多是在进程死亡后释放所有文件描述符的副作用,而不是直接由进程清理完成。
然而,我猜测你遇到了网络编程中的一个常见问题。如果我猜对了,你的问题是当进程被杀死后,尝试绑定地址时会出现“地址正在使用”的错误(EADDRINUSE),那么你就遇到了套接字的TIME_WAIT。
如果是这种情况,你可以等待超时,通常为60秒,或者修改套接字以允许立即重用,方法如下。
int sock, ret, on;
struct sockaddr_in servaddr;
sock = socket( AF_INET, SOCK_STREAM, 0 ):
/* Enable address reuse */
on = 1;
ret = setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) );
kill -9
终止客户机进程,则四方关闭握手永远无法完成。但这不应该在服务器上留下打开的连接,所以您仍然需要获取网络转储文件以确保发生了什么事情。kill -9
命令也应该让套接字关闭,并将服务器置于 CLOSE_WAIT 状态,这不应该真正引起问题。我所描述的半开放状态通常是由电源、链路或路由问题引起的,客户端会突然消失。 - JimB