wait函数与waitpid函数(僵尸进程)

  当子进程退出时,内核会向父进程发送SIGCHLD信号,子进程的退出是个异步事件(子进程可以在父进程运行的任何时刻终止)

  子进程退出时,内核将子进程置为僵尸状态,这个进程称为僵尸进程。它只保留最小的一些内核数据结构,以便父进程查询子进程的退出状态。父进程查询子进程的退出状态可以用wait/waitpid函数。

wait函数: pid_t  wait(int  *status)  函数参数:status 该函数可以获得等待子进程的信息。返回值:子include<unistd.h>

#include<sys/wait.h>
#include<stdlib.h> #include<stdio.h> #include<errno.h> #include<string.h> #include<signal.h> #define ERR_EXIT(m) do { perror(m); exit(EXIT_FAILURE); }while(0) int main(int argc,char *argv[]){ pid_t pid; pid=fork(); if(pid == -1) ERR_EXIT("fork error"); if(pid == 0){ printf("this is child "); //exit(100);
     abort(); } printf(
"this is parent "); int status,ret; ret=wait(&status);//等待子进程退出
   printf("ret = %d,pid = %d ",ret,pid);
   if (WIFEXITED(status))
      printf("child exited normal. exit status=%d ",WEXITSTATUS(status));
   else
      printf("child exited
abnormal ");
return 0; }

wait系统调用会使父进程暂停执行,直到它的一个子进程结束为止。返回的是子进程的PID,它通常是结束的子进程。状态信息允许父进程判定子进程的退出状态,即从子进程的main函数返回的值或子进程中exit语句的退出码。如果status不是一个空指针,状态信息将被写入它指向的位置。

waitpid函数:pid_t waitpid(pid_t pid, int *status, int options); 函数功能:用来等待某个特定进程的结束。

参数:status:若不为空,会把状态信息写到它指向的位置;options允许改变waitpid的行为,最有用的一个选项是WNOHANG,它的作用是防止waitpid把调用者的执行挂起。

参数中pid的值可以是:

1、<-1:等待的子进程的进程组ID等于(-pid)   pid的绝对值。

2、-1: waitpid(-1, &status, 0)  等价于  wait(&status);

3、0: 等待的子进程的进程组ID等于调用进程的进程组ID(同一个进程组)

4、>0:表示等待子进程号码为pid的进程的退出(等待特定子进程)

wait与waitpid的区别:

  在一个子进程终止前,wait使其调用者阻塞;而waitpid有一个选项,可使调用者不阻塞。

waitpid并不等待第一个终止的子进程——它有若干个选择项,可以控制它所等待的特定进程。实际上,wait函数是waitpid函数的一个特例。

僵尸进程:

  当一个子进程结束运行时,它与其父进程之间的关联还会保持到父进程也正常地结束,或者父进程调用了wait才终止;

  进程表中,代表子进程地数据项是不会立刻释放地,虽然不再活跃了,可子进程还停留在系统里。因为它的退出码还是需要保存起来以备父进程中后续地wait调用。它被称为一个“僵进程”。

如何避免僵尸进程:

1、调用wait或者waitpid函数,查询子进程退出状态,才方法父进程会被挂起;

2、如果不想让父进程挂起,可以在父进程中加入一条语句:signal(SIGCHLD,SIG_IGN);表示父进程忽略SIGCHLD信号,该信号是子进程退出地时候向父进程发送的。

原文地址:https://www.cnblogs.com/wsw-seu/p/10853638.html