6进程原语:wait()和waitpid()函数

简介:  1 wait/waitpid 僵尸进程: 子进程退出,父进程没有回收子进程资源(PCB),则子进程变成僵尸进程 孤儿进程: 父进程先于子进程结束,则子进程成为孤儿进程,子进程的父进程成为1号 进程init进程,称为init进程领养孤儿进程 2依赖的头文件 #include <sys/types.h> #include <


1 wait/waitpid

僵尸进程: 子进程退出,父进程没有回收子进程资源(PCB),则子进程变成僵尸进程

孤儿进程: 父进程先于子进程结束,则子进程成为孤儿进程,子进程的父进程成为1

进程init进程,称为init进程领养孤儿进程

2依赖的头文件

#include <sys/types.h>

#include <sys/wait.h>

3函数声明

pid_t wait(int *status);

pid_t waitpid(pid_t pid, int *status, intoptions);

 

The value of pid can be:

      < -1   meaning wait for anychild process whose  process  group ID  is

              equal to the absolute value ofpid.

 

      -1     meaning wait for any childprocess.

 

      0      meaning  wait for  any  child process whose process group ID is

              equal to that of the callingprocess.

 

      > 0    meaning wait for thechild whose process  ID  is equal  to  the

              value of pid.

< -1 回收指定进程组内的任意子进程

-1 回收任意子进程

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

> 0 回收指定ID的子进程

3.说明:

一个进程在终止时会关闭所有文件描述符,释放在用户空间分配的内存,但它的PCB

保留着,内核在其中保存了一些信息:如果是正常终止则保存着退出状态,如果是异常终止

则保存着导致该进程终止的信号是哪个。这个进程的父进程可以调用waitwaitpid获取这

些信息,然后彻底清除掉这个进程。我们知道一个进程的退出状态可以在Shell中用特殊变

$?查看,因为Shell是它的父进程,当它终止时Shell调用waitwaitpid得到它的退出状

态同时彻底清除掉这个进程。

如果一个进程已经终止,但是它的父进程尚未调用waitwaitpid对它进行清理,这时

的进程状态称为僵尸(Zombie)进程。任何进程在刚终止时都是僵尸进程,正常情况下,僵

尸进程都立刻被父进程清理了,为了观察到僵尸进程,我们自己写一个不正常的程序,父进

fork出子进程,子进程终止,而父进程既不终止也不调用wait清理子进程:

#include <unistd.h>

#include <stdlib.h>

int main(void)

{

pid_t pid=fork();

if(pid<0) {

perror("fork");

exit(1);

}

if(pid>0) { /* parent */

while(1);

}

/* child */

return 0;

}

若调用成功则返回清理掉的子进程id,若调用出错则返回-1。父进程调用wait

waitpid时可能会:

* 阻塞(如果它的所有子进程都还在运行)。

* 带子进程的终止信息立即返回(如果一个子进程已终止,正等待父进程读取其终止信

息)。

* 出错立即返回(如果它没有任何子进程)。

这两个函数的区别是:

* 如果父进程的所有子进程都还在运行,调用wait将使父进程阻塞,而调用waitpid时如果在options参数中指定WNOHANG可以使父进程不阻塞而立即返回0

* wait等待第一个终止的子进程,而waitpid可以通过pid参数指定等待哪一个子进程。

可见,调用waitwaitpid不仅可以获得子进程的终止信息,还可以使父进程阻塞等待子进

程终止,起到进程间同步的作用。如果参数status不是空指针,则子进程的终止信息通过

这个参数传出,如果只是为了同步而不关心子进程的终止信息,可以将status参数指定为

NULL

waitpid

The value  of  options is an OR of zero or more of the following con

      stants:

      WNOHANG     return immediately ifno child has exited.

      WUNTRACED   also return if a childhas  stopped  (but not  traced  via

                   ptrace(2)).   Status for traced children which havestopped

                   is provided even if thisoption is not specified.

      WCONTINUED (since Linux 2.6.10)

                   also return if a stoppedchild has been resumed by delivery

                   of SIGCONT.

      (For Linux-only options, see below.)

If status is not NULL, wait() and waitpid()store status information in

      the int to which it points.  Thisinteger can  be  inspected with  the

      following  macros  (which take the integer itself as anargument, not a

      pointer to it, as is done in wait() and waitpid()!):

 

      WIFEXITED(status)

              returns true if the childterminated normally, that is, by call

              ing exit(3) or _exit(2), or byreturning from main().

 

      WEXITSTATUS(status)

              returns  the exit  status  of  thechild.  This consists of the

              least significant 8 bits of thestatus argument that  the  child

              specified  in a  call to exit(3) or _exit(2) oras the argument

              for a return statement inmain().  This macro should be employed

              only if WIFEXITED returned true.

 

      WIFSIGNALED(status)

              returns true if the child processwas terminated by a signal.

 

      WTERMSIG(status)

              returns  the number of the signal that caused the child process

              to terminate.  This macro should be employed only ifWIFSIGNALED

              returned true.

WCOREDUMP(status)

              returns  true if  the  child produced a core dump.  This macro

              should be employed only  if WIFSIGNALED  returned  true.  This

              macro  is  notspecified in POSIX.1-2001 and is not available on

              some UNIX implementations (e.g.,AIX,  SunOS).   Only use  this

              enclosed in #ifdef WCOREDUMP ...#endif.

 

      WIFSTOPPED(status)

              returns  true if the child process was stopped by delivery of a

              signal; this is possible only ifthe call was  done  using WUN

              TRACED or when the child is beingtraced (see ptrace(2)).

 

      WSTOPSIG(status)

              returns the number of the signalwhich caused the child to stop.

              This macro should be employedonly if WIFSTOPPED returned true.

 

      WIFCONTINUED(status)

              (since Linux 2.6.10) returns  true if  the  child process  was

              resumed by delivery of SIGCONT.

 

#include <sys/wait.h>

      #include <stdlib.h>

      #include <unistd.h>

      #include <stdio.h>

 

      int

      main(int argc, char *argv[])

      {

          pid_t cpid, w;

          int status;

 

          cpid = fork();

          if (cpid == -1) {

               perror("fork");

               exit(EXIT_FAILURE);

          }

 

          if (cpid == 0) {            /*Code executed by child */

               printf("Child PID is%ld\n", (long) getpid());

               if (argc == 1)

                   pause();                    /* Wait for signals */

               _exit(atoi(argv[1]));

} else {                    /*Code executed by parent */

               do {

                   w = waitpid(cpid,&status, WUNTRACED | WCONTINUED);

                   if (w == -1) {

                       perror("waitpid");

                       exit(EXIT_FAILURE);

                   }

 

                   if (WIFEXITED(status)) {

                       printf("exited,status=%d\n", WEXITSTATUS(status));

                   } else if(WIFSIGNALED(status)) {

                       printf("killed by signal%d\n", WTERMSIG(status));

                   } else if(WIFSTOPPED(status)) {

                       printf("stopped bysignal %d\n", WSTOPSIG(status));

                   } else if(WIFCONTINUED(status)) {

                      printf("continued\n");

                   }

               } while (!WIFEXITED(status)&& !WIFSIGNALED(status));

               exit(EXIT_SUCCESS);

          }

      }

目录
相关文章
|
1月前
|
Linux C语言
C语言 多进程编程(三)信号处理方式和自定义处理函数
本文详细介绍了Linux系统中进程间通信的关键机制——信号。首先解释了信号作为一种异步通知机制的特点及其主要来源,接着列举了常见的信号类型及其定义。文章进一步探讨了信号的处理流程和Linux中处理信号的方式,包括忽略信号、捕捉信号以及执行默认操作。此外,通过具体示例演示了如何创建子进程并通过信号进行控制。最后,讲解了如何通过`signal`函数自定义信号处理函数,并提供了完整的示例代码,展示了父子进程之间通过信号进行通信的过程。
|
29天前
|
编译器
【收藏】内核级利用通用Hook函数方法检测进程
【收藏】内核级利用通用Hook函数方法检测进程
|
2月前
|
Linux API
Linux源码阅读笔记07-进程管理4大常用API函数
Linux源码阅读笔记07-进程管理4大常用API函数
|
3月前
|
安全 API Python
`multiprocessing`是Python的一个标准库,用于支持生成进程,并通过管道和队列、信号量、锁和条件变量等同步原语进行进程间通信(IPC)。
`multiprocessing`是Python的一个标准库,用于支持生成进程,并通过管道和队列、信号量、锁和条件变量等同步原语进行进程间通信(IPC)。
|
4月前
|
运维 JavaScript Serverless
Serverless 应用引擎产品使用合集之函数计算里中FC出现函数还没有执行完进程就关闭了是什么导致的
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
|
5月前
|
Linux Shell 程序员
【进程控制】进程程序替换的原理以及exec函数族
【进程控制】进程程序替换的原理以及exec函数族
|
5月前
【进程控制】超详细讲解wait和waitpid的原理(结合代码)
【进程控制】超详细讲解wait和waitpid的原理(结合代码)
|
5月前
|
存储 算法 Unix
【创建进程】fork函数与写时拷贝
【创建进程】fork函数与写时拷贝
|
5月前
|
消息中间件 Unix Linux
【探索Linux】P.14(进程间通信 | 匿名管道 | |进程池 | pipe() 函数 | mkfifo() 函数)
【探索Linux】P.14(进程间通信 | 匿名管道 | |进程池 | pipe() 函数 | mkfifo() 函数)
80 0

相关实验场景

更多