回收子进程

简介: 回收子进程

孤儿进程

       孤儿进程:父进程先于子进程结束,则子进程成为孤儿进程。子进程的父进程变成init进程。init-->1号进程,被称为进程孤儿院。【孤儿进程是没有危害的】

      init进程会循环的wait()它的已经退出的子进程。这样,当一个子进程凄凉的结束了其生命的时候,init进程就会代表党和政府出面处理它的一切善后工作,因此,孤儿进程并不会有什么危害。

僵尸进程

       僵尸进程:进程终止,父进程尚未回收(父进程后于子进程结束)。子进程残留的资源(PCB)存放在内核中,变成了僵尸进程。僵尸进程危害很大,应尽量避免。

  • 每个进程结束之后,都会释放自己地址空间中的用户区数据,内核区的PCB没有办法自己释放掉,需要父进程去释放。(父进程的父进程是当前所在的bash,或者说终端)
  • 进程终止时,父进程尚未回收子进程残留的资源(PCB)存在于内核中,变成了僵尸进程。
  • 僵尸进程不能被 kill -9 杀死,因为已经终止了,不可能接收信号。
  • 这样会导致一个很严重的问题,如果父进程不调用wait()或waitpid()的话,那么保留的那段信息就不会释放,其进程号就会被一直占用(进程号存在内核区中的PCB中),但是进程号能使用的进程号是有限的(pid_t 也是无符号整型而已),如果大量的僵尸进程产生,将因为没有可用的进程号而导致系统不能产生新的进程。
  • 解决僵尸进程的方法:1).杀死其父进程 【这种方式显然不合理,父进程的工作没有做完就杀死,芭比Q了】 2).在父进程中调用wait()  waitpid()回收子进程残留的资源。    

进程回收

  • 在每个进程退出的时候,内核释放该进程的几乎所有的资源,用户区的所有资源。包括打开的文件、占用的内存等。但仍然为其保留一定的信息,这些信息主要指进程控制块PCB的信息(进程号、进程退出状态)。
  • 父进程可以通过调用wait()或者waitpid()得到它的退出状态,同时彻底清除掉这个进程。
  • wait()和waitpid()函数的功能一样,区别在于wait()函数会阻塞。 waitpid()可以设置非阻塞,waitpid()还可以指定等待哪个子进程结束。
  • 一次wait()和waitpid()调用只能清理一个子进程,清理多个子进程需要使用循环。
  • wait()和waitpid()采用轮询的方式。    

     pid_t wait(int * wstatus);

       -功能:等待任意一个子进程结束,如果任意一个子进程结束了,此函数会回收子进程残留的资源。

       -参数:wstatus  进程退出时的状态信息,传入的是一个int类型的地址    【传出参数】

       -返回值:成功    返回被回收的子进程的id

                       失败    -1(所有的子进程都结束了,函数调用失败)

       -说明:调用wait函数的进程会被挂起(阻塞),直到它的一个子进程退出或者收到一个不能忽略的信号时才被唤醒,才继续往下执行。

       pid_t waitpid(pid_t pid,int wstatus,int options);

        -功能:回收子进程残留的资源。

       -参数:wstatus  进程退出时的状态信息,传入的是一个int类型的地址    【传出参数】

                   pid:

                               >0 回收指定ID的子进程

                               -1  回收任意子进程(相当于wait)

                               0   回收和当前调用waitpid一个组的所有子进程

                               <-1 回收指定进程组内的任意子进程(取绝对值)

                 options:指定是否阻塞    

                               0     阻塞

                               WNOHANG  不阻塞

         -返回值:成功    返回被回收的子进程的id

                       失败    -1(指定的所有的子进程都结束了,函数调用失败)

WSTATUS:

       WIFEXITED(status)  为非0  --->程序正常退出

                                                            WEXITSTATUS(status):获取进程退出状态

       WIFSIGNALED(status) 为非0 --->程序异常退出

                                                              WTERMSIG(status):取得使进程退出那个信号

       WIFSTOPPED(status) 为非0 -->程序处于暂停状态

                                                               WSTOPSIG(status):取得使进程暂停那个信号

     WIFCONTINUED(status):进程退出后已继续运行。

#include  <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
int main(){
    //创建子进程
    pid_t pid = fork();
    if(pid == -1){
        perror("fork");
        return 0;
    }
    if(pid > 0){    //父进程
        int status;
        pid_t wpid = wait(&status);
        if(WIFEXITED(status)){
            printf("status %d\n",WEXITSTATUS(status));  
        }else if(WIFSIGNALED(status)){
            printf("status %d\n",WTERMSIG(status)); 
        }
    }else if(pid == 0){
        printf("child child childXXXXXXXXXXX\n");
        sleep(2);
        while(1){
        }
    }
    return 0;
}

                               

       

 

#include  <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
int main(){
    //创建子进程
    pid_t pid = fork();
    if(pid == -1){
        perror("fork");
        return 0;
    }
    if(pid > 0){    //父进程
        int status;
        pid_t wpid = waitpid(-1,&status,WNOHANG);
        if(WIFEXITED(status)){
            printf("status %d\n",WEXITSTATUS(status));  
        }else if(WIFSIGNALED(status)){
            printf("status %d\n",WTERMSIG(status)); 
        }
    }else if(pid == 0){
        printf("child child childXXXXXXXXXXX\n");
        sleep(2);
        while (1)
        {
            /* code */
        }
    }
    return 0;
}
相关文章
|
6月前
|
监控 安全 Unix
进程回收的实现方式与注意事项:Linux C/C中的回收机制
进程回收的实现方式与注意事项:Linux C/C中的回收机制
335 1
|
C语言
C语言 父进程fork()出的多个子进程在结束后,父进程如何回收?
我在网上找了半天都是在说wait()和waitpid()的详解或者是单个子进程的回收。答非所问。 很简单,根据wait()或者waitpid()的函数特性。没有子进程时返回-1。
83 0
|
3月前
|
C语言
【C语言】多进程创建和回收
【C语言】多进程创建和回收
66 0
让“父进程”可以有自己的工作,不需要因为为了“子进程”回收资源而堵塞。但也要满足“子进程”退出后的资源能被立马回收。(不能使用任何的进程通信机制 比如:信号等)
让“父进程”可以有自己的工作,不需要因为为了“子进程”回收资源而堵塞。但也要满足“子进程”退出后的资源能被立马回收。(不能使用任何的进程通信机制 比如:信号等)
|
6月前
|
Linux
Linux下的系统编程——进程的执行与回收(八)
Linux下的系统编程——进程的执行与回收(八)
52 1
Linux下的系统编程——进程的执行与回收(八)
|
6月前
进程之 回收子进程之避免僵尸进程的产生
wait() 与 waitpid() 函数的使用.
71 0
|
程序员 Linux Shell
【CSAPP】进程控制 | 系统调用错误处理 | 进程状态 | 终止进程 | 进程创建 | 回收子进程 | 与子进程同步(wait/waitpid) | execve 接口
【CSAPP】进程控制 | 系统调用错误处理 | 进程状态 | 终止进程 | 进程创建 | 回收子进程 | 与子进程同步(wait/waitpid) | execve 接口
208 0
|
Linux
linux基础——进程的退出及资源回收
linux基础——进程的退出及资源回收
455 0
linux基础——进程的退出及资源回收
|
Shell Linux C语言
【Linux进程】六、wait()函数——子进程回收
【Linux进程】六、wait()函数——子进程回收
475 0
【Linux进程】六、wait()函数——子进程回收

热门文章

最新文章

相关实验场景

更多
下一篇
无影云桌面