僵尸进程:就是已经结束了的进程,但是没有从进程表中删除。太多了会导致进程表里面条目满了,进而导致系统崩溃,倒是不占用其他系统资源。
僵尸进程的查看:
ps -ef
出现:
root 13028 12956 0 10:51 pts/2 00:00:00 [ls] <defunct>
最后有defunct的标记,就表明是僵尸进程。
产生的原因:
每个Linux进程在进程表里都有一个进入点(entry),核心程序执行该进程时使用到的一切信息都存储在进入点。当用ps命令察看系统中的进程信息时,看到的就是进程表中的相关数据。当以fork()系统调用建立一个新的进程后,核心进程就会在进程表中给这个新进程分配一个进入点,然后将相关信息存储在该进入点所对应的进程表内。这些信息中有一项是其父进程的识别码。当这个进程走完了自己的生命周期后,它会执行exit()系统调用,此时原来进程表中的数据会被该进程的退出码(exit code)、执行时所用的CPU时间等数据所取代,这些数据会一直保留到系统将它传递给它的父进程为止。由此可见,defunct进程的出现时间是在子进程终止后,但是父进程尚未读取这些数据之前。
产生的例程:
#include "sys/types.h"
#include "sys/wait.h"
#include "stdio.h"
#include "unistd.h"
int main(int argc, char* argv[])
{
while(1)
{
pid_t chi = fork();
if(chi == 0)
{
execl("/bin/ls",NULL);
}
sleep(2);
}
}
对付这种的方法:
外部的方法:
执行pstree,看到:
|-sshd-+-sshd---bash
| |-sshd---sftp-server
| `-sshd-+-bash---vi
| |-bash---myfork---2*[ls]
也就是主进程是myfork
将myfork干掉就可以了
编程的方法:
1、主进程等待子进程
#include "sys/types.h"
#include "sys/wait.h"
#include "stdio.h"
#include "unistd.h"
int main(int argc, char* argv[])
{
while(1)
{
pid_t chi = fork();
if(chi == 0)
{
execl("/bin/ls",NULL);
}
int status;
wait(&status);
sleep(2);
}
}
也就是加上了wait
2、在主进程里面补充对child 退出的signal的处理:
void sig_child(int signo){
pid_t pid;
int stat,i;
while((pid = waitpid(-1, &stat, WNOHANG)) > 0);
return;
}
signal(SIGCHLD,sig_child);
分享到:
相关推荐
4. **PS命令显示**:使用`ps`命令查看进程时,僵尸进程会显示为“Z<”或“defunct”。 #### 四、如何避免僵尸进程 为了避免僵尸进程的产生,可以通过以下几种方式: 1. **调用`wait`或`waitpid`函数**:父进程...
在 unix 或 unix-like 的系统中,当一个子进程退出后,它就会变成一个僵尸进程,如果父进程没有通过 wait 系统调用来读取这个子进程的退出状态的话,这个子进程就会一直维持僵尸进程状态。 Zombie process – ...
例如,通过定期检查是否存在僵尸进程,可以避免系统资源的浪费;通过调整进程的优先级,可以在必要时提高关键任务的执行效率。总之,掌握Linux进程状态不仅能够帮助我们诊断问题,还能够在日常运维工作中提高系统的...
- 上面的命令用于查找僵尸进程。 **2. 检查特定进程状态** - 可以通过循环遍历特定进程名来检查它们的状态。 ```bash PROC="BankServer|aibank BankClient|aibank tgmp|icbc" for i in $PROC do process_...
- **清除僵尸进程**:使用 `ps aux | grep defunct | awk '{print $2}' | xargs kill -9` 清除系统中的僵尸进程。 - **将大于 120M 内存的 php-cgi 都杀掉**:执行 `ps aux | grep 'php-cgi' | awk '$4 > 120 {print...