如何处理僵尸进程?

僵尸进程解析

如果你经常使用 Linux,你应该遇到这个术语“僵尸进程”。 那么什么是僵尸进程? 它们是怎么产生的? 它们是否对系统有害? 我要怎样杀掉这些进程? 下面将会回答这些问题。

什么是僵尸进程?

我们都知道进程的工作原理。我们启动一个程序,开始我们的任务,然后等任务结束了,我们就停止这个进程。 进程停止后, 该进程就会从进程表中移除。

你可以通过 System-Monitor 查看当前进程。

但是,有时候有些程序即使执行完了也依然留在进程表中。

那么,这些完成了生命周期但却依然留在进程表中的进程,我们称之为 “僵尸进程”。

内容

它们是如何产生的?

当你运行一个程序时,它会产生一个父进程以及很多子进程。 所有这些子进程都会消耗内核分配给它们的内存和 CPU 资源。

这些子进程完成执行后会发送一个 Exit 信号然后死掉。这个 Exit 信号需要被父进程所读取。父进程需要随后调用 wait 命令来读取子进程的退出状态,并将子进程从进程表中移除。

若父进程正确第读取了子进程的 Exit 信号,则子进程会从进程表中删掉。

但若父进程未能读取到子进程的 Exit 信号,则这个子进程虽然完成执行处于死亡的状态,但也不会从进程表中删掉。

僵尸进程对系统有害吗?

不会。由于僵尸进程并不做任何事情, 不会使用任何资源也不会影响其它进程, 因此存在僵尸进程也没什么坏处。 不过由于进程表中的退出状态以及其它一些进程信息也是存储在内存中的,因此存在太多僵尸进程有时也会是一些问题。

你可以想象成这样:

“你是一家建筑公司的老板。你每天根据工人们的工作量来支付工资。 有一个工人每天来到施工现场,就坐在那里, 你不用付钱, 他也不做任何工作。 他只是每天都来然后呆坐在那,仅此而已!”

这个工人就是僵尸进程的一个活生生的例子。但是, 如果你有很多僵尸工人, 你的建设工地就会很拥堵从而让那些正常的工人难以工作。

那么如何找出僵尸进程呢?

打开终端并输入下面命令:
ps aux | grep Z

会列出进程表中所有僵尸进程的详细内容。

如何杀掉僵尸进程?

正常情况下我们可以用 SIGKILL
信号来杀死进程,但是僵尸进程已经死了, 你不能杀死已经死掉的东西。 因此你需要输入的命令应该是
kill -s SIGCHLD pid

将这里的 pid 替换成父进程的进程 id,这样父进程就会删除所有以及完成并死掉的子进程了。

你可以把它想象成:

"你在道路中间发现一具尸体,于是你联系了死者的家属,随后他们就会将尸体带离道路了。"

不过许多程序写的不是那么好,无法删掉这些子僵尸(否则你一开始也见不到这些僵尸了)。 因此确保删除子僵尸的唯一方法就是杀掉它们的父进程。


在Python中,你可以使用`subprocess`模块的`check_call()`、`check_output()`或`run()`方法来管理和监控子进程,并利用它们提供的选项来避免僵尸进程。当你启动一个子进程时,通常应该使用`with`语句结合`subprocess.Popen`,这样在`with`块结束后,子进程会被自动关闭并等待其完成。 以下是一个简单的例子,展示了如何使用`subprocess`来确保子进程完成后正确处理: ```python import subprocess # 启动子进程并捕获其输出 with subprocess.Popen(['your_command', 'arg1', 'arg2'], stdout=subprocess.PIPE) as proc: # 执行其他任务... output = proc.communicate()[0] # 确保子进程已经结束,并处理可能存在的退出码 if proc.returncode != 0: print(f"子进程退出失败,返回码:{proc.returncode}") else: print("子进程成功执行") # 此处子进程不会成为僵尸进程,因为它会在with块结束后被妥善处理 ``` 如果你希望手动处理进程的退出,可以使用`wait()`或`waitpid()`: ```python import os pid = os.fork() if pid == 0: # 子进程执行... os._exit(0) else: # 父进程 child_status = os.waitpid(pid, os.WNOHANG) if child_status[0] == 0: print("子进程已经结束") else: print("子进程还在运行") ``` 在这个例子中,`os.waitpid()`用于检查子进程是否已经结束。如果没有立即结束,它将返回`None`,表示需要再次调用以检查。 总之,在Python中,正确的资源管理可以避免僵尸进程问题。如果遇到僵尸进程,通常意味着你的代码流程设计存在问题,需要找出并修复。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值