报错处理(2)终止多线程父进程后子进程还存在
第一步:找到主进程ID (PID)
后台任务是由一个主进程(你启动nohup时创建的那个)和很多子进程(multiprocessing创建的worker)组成的。我们只需要杀死主进程,它就会自动终止所有的子进程。运行ps命令来查找:
ps -ef | grep 当时运行的程序名字.py这个命令会列出所有包含当时运行的程序名字.py的进程。你需要找到那个“族谱”里的最顶层父进程。一个更简单的方法是使用pgrep:
pgrep -f "python .* 当时运行的程序名字.py"pgrep -f会根据完整的命令行来查找进程。如果“当时运行的程序名字.py”是你系统里唯一一个这样运行的,它可能会返回一个或多个PID。
一个更可靠的方法,是结合ps的父子进程关系来找:
ps -ef --forest | grep 当时运行的程序名字.py--forest会以树状结构显示进程关系,你很容易就能找到最顶端的那个python ... 当时运行的程序名字.py ...进程
这里我运行了ps -ef | grep 当时运行的程序名字.py得到了一堆进程,把结果给gpt看,问它父进程是哪一个,
ps -ef的输出格式是: UID PID PPID C STIME TTY TIME CMD UID: 用户ID (liyiting) PID: 进程ID (Process ID) PPID: 父进程ID (Parent Process ID) CMD: 完整的命令行帮我找到了父进程的PID号
第二步:使用 kill 命令终止进程
终止进程 (推荐首选):
一旦你确定了主进程的PID(假设是3073454),就可以使用kill命令。kill 3073454这个命令会向进程发送一个TERM(terminate)信号,告诉它“请自行清理并退出”。这给了程序一个机会来正常关闭文件等。
但是这样以后它的子进程并没有被kill,这一点可以通过看第一步的ps命令可以看到,进程数并没有减少。gpt解释:
父进程被kill,子进程成为“孤儿进程”
可能性: 这是更常见的情况。当你kill父进程时,它的子进程会立即失去它们的“家长”。
会发生什么: 这些“孤儿进程”不会立即消失。操作系统内核会介入,并将它们的父进程ID(PPID)重新设置为 1(即init或systemd进程)。init进程会成为它们的新“养父”,并负责在它们最终结束后回收其资源。
关键点: 虽然这些子进程的PP-ID变了,但它们自己并不会自动退出!它们会继续执行它们正在做的工作,直到任务完成或遇到错误而退出。
如何验证: 运行ps -ef | grep 当时运行的程序名字.py,然后仔细查看那些之前属于SnapHiC2的子进程(例如PID 3314368, 3314373等),检查它们的PPID列。如果它们的PPID从3308896变成了1,那就证实了它们已经成为孤儿进程。
运行下面的程序验证我的猜想
ps -o pid,ppid,stat,cmd -f --pid $(pgrep -f "你的运行的python文件的路径")例如这个文件夹和文件是我当时运行的文件:
ps -o pid,ppid,stat,cmd -f --pid $(pgrep -f "Snaphic2/SnapHiC-0.2.2/snap.py")查看输出结果中,那些PID以33...开头的进程,它们的PPID(父进程ID)那一列的值是否为1,是1则说明确实如上推断。
所以直接命令行清除子进程:
pkill -f "Snaphic2/SnapHiC-0.2.2/snap.py"ps命令验证一下确实没有了,结束。
