进组控制

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/isunbin/article/details/88856557

二、函数wait和waitpid

一个进程在终止时会关闭所有文件描述符,释放在用户空间释放的内存,但它的PCB还保留着,内核在其中保存一些信息:如果是正常终止时则保存着退出状态,如果是异常终止则保存着导致该进程终止的信号是哪个,这个进程的父进程可以调用wait或waitpid获取这些信息,然后彻底清除这个进程,我们知道一个进程的退出状态可以在shell用特殊变量$?查看,因为shell是它的父进程,当它终止时shell调用wait或waitpid得到它的退出状态同时彻底清除这个进程。

1. wait函数原型:一次只能回收一个子进程

pid_t wait(int *status); 

 当进程终止时,操作系统隐式回收机制会:1. 关闭所有的文件描述符 2. 释放用户空间分配的内存。内核PCB仍存在,其中保存该进程的退出状态。(正常终止--------退出值;异常终止-------终止信号)

  • WIFEXITED(status):为非0  进程正常结束;WEXITSTATUS(status) :如上宏为真,使用此宏  获取进程退出状态(exit的参数)
  •   WIFSIGNALED(status):为非0    进程异常终止; WTERMSIG(status):如上宏为真,使用此宏  获取进程终止的那个信号编号
  • WIFSTOPPED(status) :为非0    进程处于暂停状态; WSTOPSIG(status):如上宏为真,使用此宏  获取进程暂停的那个信号编号; WIFCONTINUE(status):为真     进程暂停后已经继续运行。
     


2. 测试代码:

#include <stdio.h>
#include <unistd.h>
#include<sys/wait.h>
 
int main(int argc, const char* argv[])
{
    pid_t pid = fork();
 
    if (pid > 0) 
    {   // 父进程
        printf("parent process, pid = %d, ppid = %d\n", getpid(), getppid());
        int status;
        pid_t wpid = wait(&status);
 
        if (WIFEXITED(status)) 
            printf("exit value: %d", WEXITSTATUS(status));

        if (WIFSIGNALED(status)) 
            printf("exit by signal: %d\n", WTERMSIG(status)); //是否被信号杀死

        printf(" die child pid = %d\n", wpid);
    }
    else if(pid == 0) 
    {
        sleep(1);
        printf("child process, pid = %d, ppid = %d\n", getpid(), getppid());    
    }
    for (int i = 0; i<5; ++i) 
        printf(" i = %d\n", i);
    return 9;
}


2. 函数waitpid原型:作用同wait,但可指定pid进程清理,可以不阻塞( 一次只能回收一个子进程)

pid_t wait(pid_t pid, int *staloc, int options);

参数pid:

  • pid == -1:回收任一子进程
  • pid  >  0 :回收指定pid的进程
  • pid == 0 :回收与父进程同一个进程组的任一个子进程
  • pid < -1  :回收指定进程组内的任意子进程

参数 options:

  • 设置为WNOHANG:函数不阻塞;
  • 设置为0:函数阻塞。

猜你喜欢

转载自blog.csdn.net/isunbin/article/details/88856557