Linux的僵尸进程处理1

Linux中有两种异常的进程:
  1.孤儿进程:应用通过fork进程后,父进程被kill或者exit,该父进程的子进程被1号进程接管。linux内核启动时候回启动0号进程,启动完毕后0号进程就处于空闲状态,所有的进程的父进程都是有1号进程fork出来的。
  2.僵尸进程:fork操作出来的父子进程,子进程收到kil -9的操作或者exit的操作,子进程的内存和CPU资源被操作系统回收,但是PCB块还会在内核中。Linux进程的控制是依靠PCB块的,PCB块记录了进程的运行信息,比如时间片,运行时间,内存资源等等。linux内核按照不同的进程状态把进程放到不同的状态的list中,每次内核会遍历这些list执行对应的进程。


如下就是一个简单的例子,设计到了进程间管道通信、信号注册,信号处理。

#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#define TDATA 888
void clear_up(int sig)  //收到exit或者kill -9的信号,需要处理的事情
{
    while(1)
    {
        pid_t p = wait(NULL);
        if(p == -1) break;
        fprintf(stdout,"******recyle %d ok******\n",p);
    }
}
void exit_fuc()//收到sigint的信号的处理
{
    printf("*********exit %d******\n",getpid()); 
    exit(0);
}
int main(void) {
    int fd[2]; //管道处理,两个进程的通信
    signal(SIGCHLD,&clear_up); //信号的注册,改信号是发送退出信号给操作系统时候需要处理的事情
    signal(SIGINT,&exit_fuc); //信号注册
    pid_t pid = -1;
    if(pipe(fd) == -1)
    {
        return -1;
    }
    int w_fd = fd[1]; //管道中的fd[1]是写的操作
    int r_fd = fd[0];//管道中的fd[0]的是读操作
    pid = fork(); //fork一个子进程
    assert(pid != -1);
    if(pid > 0)
    {
        close(r_fd);
        char buf[4] = {'\0'};
        int c_sec = 0;
        while(1)
        {
            fprintf(stdout,"I am a parent =%d,my child =%d\n\n",getpid(),getppid());
            c_sec++;
            if(c_sec  == 2)
            {
                printf("*********send %d********\n",TDATA); //父进程发送消息
                memset(buf,'\0',sizeof(int));
                sprintf(buf,"%d",TDATA);
                write(w_fd,buf,sizeof(int));//写到管道
                system("ps -ef|grep -v 'grep'|grep 'tx1'");
            }
            sleep(2);
        }
    }
    else 
    {
        close(w_fd);
        char buf[4] = {'\0'};
        while(1)
        {
            fprintf(stdout,"I am a child =%d,my parent =%d\n\n",getpid(),getppid());
            system("ps -ef|grep -v 'grep'|grep 'tx1'");
            memset(buf,'\0',4);
            read(r_fd,buf,sizeof(int));
            if(strlen(buf) > 0 && atoi(buf) == TDATA)
            {
                fprintf(stdout,"********recive  %s***********\n",buf); //如果收到内容
                kill(getpid(),9); //给操作系统发送9号信号
            }
            sleep(1);
        }
    }
    return 0;
}

 

 

运行结果:
zhoulin@:~/code/c/demo:./tx1
I am a parent =39267,my child =7742

I am a child =39268,my parent =39267

zhoulin  39267  7742  0 20:52 pts/1    00:00:00 ./tx1 --父进程
zhoulin  39268 39267  0 20:52 pts/1    00:00:00 ./tx1 --子进程
I am a parent =39267,my child =7742

*********send 888******** 主进程发送内容
********recive  888*********** 子进程接受内容
zhoulin  39267  7742  0 20:52 pts/1    00:00:00 ./tx1 --父进程
zhoulin  39268 39267  0 20:52 pts/1    00:00:00 [tx1] <defunct> --子进程进行了exit操作,linux内核中的pcb并没有回收
******recyle 39268 ok****** --主进程监听到了kill 9的信号,进行的wait操作,回收了僵尸进程。
I am a parent =39267,my child =7742 --此时再次打印的就只有父进程了

^C*********exit 39267****** --Ctrl+c的发送sigint的信号,该信号对应的函数exit_fuc的处理,就是退出父进程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值