🐶博主主页:@ᰔᩚ. 一怀明月ꦿ
❤️🔥专栏系列:线性代数,C初学者入门训练,题解C,C的使用文章,「初学」C++,linux
🔥座右铭:“不要等到什么都没有了,才下定决心去做”
🚀🚀🚀大家觉不错的话,就恳求大家点点关注,点点小爱心,指点指点🚀🚀🚀
目录
return
exit()
_exit()
进程等待
什么是进程等待
为什么要进行等待
如何进行等待
在子进程运行期间,父进程有没有调用wait?在干嘛呢?
waitpid
验证一下,程序正常终止时,status低16位的高8位是退出码
验证一下,程序正常终止时,status低16位的高8位是退出码
验证一下,程序正常终止时,status低16位的高8位是退出码,低八位是退出信号
父进程如何得知子进程的退出信息呢?wait/waitpid(系统调用)编辑
进行位运算太麻烦了,使用os自带函数验证status
创建多个子进程,通过waitpid等待子进程并回收资源
我们为什么不用全局变量获取子进程的退出信息?而用系统调用(WEXITSTATUS(status))
waitpid中的options
return
return
是用于从函数中返回值并结束函数的执行,而exit()
是用于终止整个程序的执行。在其他函数进行return,表示的是函数调用的结束,main的return表示的是进程的退出
exit() 和 _exit() 都是用于退出程序的函数,但它们有一些不同之处。
exit() 函数是 C 标准库中的函数,而 _exit() 函数是 POSIX 标准中定义的函数。
exit() 函数会执行一系列清理工作,例如关闭文件流、释放内存等,然后调用标准库函数 atexit() 注册的清理函数,最后终止程序。
_exit() 函数会立即终止进程,不会执行任何清理工作,也不会调用 atexit() 注册的函数。
在使用多线程的程序中,exit() 函数会先终止所有线程,然后执行清理工作,而 _exit() 函数则会直接终止进程,不会考虑其他线程。
因此,如果需要执行一些清理工作或者确保所有线程都正常终止,可以使用 exit() 函数;如果需要立即终止程序而不执行任何清理工作,可以使用 _exit() 函数。
exit()
[BCH@hcss-ecs-6176 10_31]$ cat myprocess.c #include<stdio.h> #include<unistd.h> #include<stdlib.h> int main() { printf("you can sleep me!”);\\没有\n sleep(3); exit(1); } [BCH@hcss-ecs-6176 10_31]$ ./myprocess you can sleep me![BCH@hcss-ecs-6176 10_31]$
_exit()
[BCH@hcss-ecs-6176 10_31]$ cat myprocess.c #include<stdio.h> #include<unistd.h> #include<stdlib.h> int main() { printf("you can sleep me!"); sleep(3); _exit(1); } [BCH@hcss-ecs-6176 10_31]$ ./myprocess [BCH@hcss-ecs-6176 10_31]$
进程等待
之前讲过,子进程退出,父进程如果不管不顾,就可能造成僵尸进程的问题,进而造成内存泄漏。另外,进程一旦变成僵尸状态,那就刀枪不入,“杀人不眨眼”的kill -9 也无能为力,因为谁也没有办法杀死一个已经死去的进程。最后,父进程派给子进程的任务完成的如何,我们需要知道。如,子进程运行完成,结果对还是不对,或者是否正常退出。父进程通过进程等待的方式,回收子进程资源,获取子进程退出信息
什么是进程等待
通过wait/waitpid的方式,让父进程(一般)对子进程进行资源回收的等待过程
为什么要进行等待
1)解决子进程僵尸问题带来的泄漏问题
2)父进程为什么要创建子进程?要让子进程来完成任务。子进程将任务完成的如何,父进程要不要知道呢?——需要通过进程等待的方式,获取子进程退出的信息——那两个数字(信号和退出码)——不是必须的,但是系统需要提供这样的基础功能!
如何进行等待
wait——先验证2个问题,将子进程Z->x(x是瞬时状态)
wait只能够等待任意一个子进程
将子进程和父进程同时跑5秒,5秒后子进程结束,父进程此时sleep5秒,可以观测出此时子进程的状态是Z状态,5秒后通过wait将子进程由Z变为X状态,系统就回收了资源,再过10秒父进程退出 #include<stdio.h> #include<unistd.h> #include<stdlib.h> void Worker() { int cnt=5; while(cnt--) { printf("I am child process,pid: %d ,ppid :%d,cnt:%d\n",getpid(),getppid(),cnt); sleep(1); } } int main() { pid_t id=fork(); if(id==0) { //child Worker(); exit(0); } else { sleep(10); //father pid_t rid=wait(NULL); if(rid==id) { printf("wait sucess,pid:%d \n",getpid()); } sleep(10); } return 0; } [BCH@hcss-ecs-6176 10_31]$ while :; do ps ajx | head -1 && ps ajx | grep myprocess | grep -v grep; sleep 1; echo "------------------------------------------------------"; done PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 10461 2676 2676 10461 pts/0 2676 S+ 1000 0:00 ./myprocess 2676 2677 2676 10461 pts/0 2676 S+ 1000 0:00 ./myprocess ------------------------------------------------------ PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 10461 2676 2676 10461 pts/0 2676 S+ 1000 0:00 ./myprocess 2676 2677 2676 10461 pts/0 2676 S+ 1000 0:00 ./myprocess ------------------------------------------------------ PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 10461 2676 2676 10461 pts/0 2676 S+ 1000 0:00 ./myprocess 2676 2677 2676 10461 pts/0 2676 S+ 1000 0:00 ./myprocess ------------------------------------------------------ PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 10461 2676 2676 10461 pts/0 2676 S+ 1000 0:00 ./myprocess 2676 2677 2676 10461 pts/0 2676 S+ 1000 0:00 ./myprocess ------------------------------------------------------ PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 10461 2676 2676 10461 pts/0 2676 S+ 1000 0:00 ./myprocess 2676 2677 2676 10461 pts/0 2676 S+ 1000 0:00 ./myprocess ------------------------------------------------------ PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 10461 2676 2676 10461 pts/0 2676 S+ 1000 0:00 ./myprocess 2676 2677 2676 10461 pts/0 2676 Z+ 1000 0:00 [myprocess] <defunct> ------------------------------------------------------ PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 10461 2676 2676 10461 pts/0 2676 S+ 1000 0:00 ./myprocess 2676 2677 2676 10461 pts/0 2676 Z+ 1000 0:00 [myprocess] <defunct> ------------------------------------------------------ PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 10461 2676 2676 10461 pts/0 2676 S+ 1000 0:00 ./myprocess 2676 2677 2676 10461 pts/0 2676 Z+ 1000 0:00 [myprocess] <defunct> ------------------------------------------------------ PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 10461 2676 2676 10461 pts/0 2676 S+ 1000 0:00 ./myprocess 2676 2677 2676 10461 pts/0 2676 Z+ 1000 0:00 [myprocess] <defunct> ------------------------------------------------------ PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 10461 2676 2676 10461 pts/0 2676 S+ 1000 0:00 ./myprocess 2676 2677 2676 10461 pts/0 2676 Z+ 1000 0:00 [myprocess] <defunct> ------------------------------------------------------ PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 10461 2676 2676 10461 pts/0 2676 S+ 1000 0:00 ./myprocess ------------------------------------------------------ PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 10461 2676 2676 10461 pts/0 2676 S+ 1000 0:00 ./myprocess ------------------------------------------------------ PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 10461 2676 2676 10461 pts/0 2676 S+ 1000 0:00 ./myprocess ------------------------------------------------------ PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 10461 2676 2676 10461 pts/0 2676 S+ 1000 0:00 ./myprocess ------------------------------------------------------ PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 10461 2676 2676 10461 pts/0 2676 S+ 1000 0:00 ./myprocess ------------------------------------------------------ PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 10461 2676 2676 10461 pts/0 2676 S+ 1000 0:00 ./myprocess ------------------------------------------------------ PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 10461 2676 2676 10461 pts/0 2676 S+ 1000 0:00 ./myprocess ------------------------------------------------------ PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 10461 2676 2676 10461 pts/0 2676 S+ 1000 0:00 ./myprocess ------------------------------------------------------ PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 10461 2676 2676 10461 pts/0 2676 S+ 1000 0:00 ./myprocess ------------------------------------------------------ PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 10461 2676 2676 10461 pts/0 2676 S+ 1000 0:00 ./myprocess ------------------------------------------------------
在子进程运行期间,父进程有没有调用wait?在干嘛呢?
如果子进程没有退出,父进程必须在wait进行阻塞等待。直到子进程僵尸,wait自动回收,返回
一般而言,谁先运行不知道,但是最后一般都是父进程最后退出!
waitpid
waitpid() 是一个系统调用,用于等待指定进程的状态发生变化并获取相关信息。它的原型是:
#include <sys/types.h> #include <sys/wait.h> pid_t waitpid(pid_t pid, int *status, int options); pid 参数指定要等待的进程ID: 如果 pid > 0,则等待指定进程ID等于 pid 的子进程。 如果 pid == -1,则等待任意子进程。 如果 pid == 0,则等待和调用进程属于同一个进程组的任意子进程。 如果 pid < -1,则等待和进程组ID等于 pid 的任意子进程。 status 参数是一个整型指针,用于存储子进程的退出状态信息。 options 参数用于指定等待选项,常见的选项有: WNOHANG:如果没有子进程退出或状态发生改变,则立即返回,不阻塞当前进程。 WUNTRACED:也等待已经停止的子进程状态改变。
waitpid() 函数会阻塞当前进程,直到指定的子进程之一退出或状态发生改变。如果指定了 status 参数,它将会被更新以反映子进程的退出状态信息。如果成功等待到子进程退出,返回值是子进程的进程ID;如果发生错误,返回值是 -1。
事例
BCH@hcss-ecs-6176 10_31]$ cat myprocess.c #include<stdio.h> #include<unistd.h> #include<stdlib.h> void Worker() { int cnt=5; while(cnt--) { printf("I am child process,pid: %d ,ppid :%d,cnt:%d\n",getpid(),getppid(),cnt); sleep(1); } } int main() { pid_t id=fork(); //子进程 if(id==0) { //child Worker(); exit(10); } else { //father int status=0;//记录 printf("wait before\n"); pid_t rid=waitpid(id,&status,0);//传入status的地址 printf("wait after\n"); if(rid==id) { printf("wait sucess,pid:%d ,status:%d \n",getpid(),status); } sleep(10); } return 0; } [BCH@hcss-ecs-6176 10_31]$ ./myprocess wait before I am child process,pid: 18911 ,ppid :18910,cnt:4 I am child process,pid: 18911 ,ppid :18910,cnt:3 I am child process,pid: 18911 ,ppid :18910,cnt:2 I am child process,pid: 18911 ,ppid :18910,cnt:1 I am child process,pid: 18911 ,ppid :18910,cnt:0 wait after wait sucess,pid:18910 ,status:2560//status并不是子进程exit的10 status是一个整数,32bit,低16位
验证一下,程序正常终止时,status低16位的高8位是退出码
[BCH@hcss-ecs-6176 10_31]$ cat myprocess.c #include<stdio.h> #include<unistd.h> #include<stdlib.h> void Worker() { int cnt=5; while(cnt--) { printf("I am child process,pid: %d ,ppid :%d,cnt:%d\n",getpid(),getppid(),cnt); sleep(1); } } int main() { pid_t id=fork(); if(id==0) { //child Worker(); exit(10);//这里10是自己定义的,所以子进程的退出码为10时时正确的 } else { //father int status=0; printf("wait before\n"); pid_t rid=waitpid(id,&status,0); printf("wait after\n"); if(rid==id) { printf("wait sucess,pid:%d ,rid:%d,status:%d,exit sign:%d,exit code:%d \n",getpid(),rid,status,status&0x7F,(status>>8)&0xFF); } } return 0; } [BCH@hcss-ecs-6176 10_31]$ ./myprocess wait before I am child process,pid: 18357 ,ppid :18356,cnt:4 I am child process,pid: 18357 ,ppid :18356,cnt:3 I am child process,pid: 18357 ,ppid :18356,cnt:2 I am child process,pid: 18357 ,ppid :18356,cnt:1 I am child process,pid: 18357 ,ppid :18356,cnt:0 wait after wait sucess,pid:18356 ,rid:18357,status:2560,exit sign:0,exit code:10 status&0x7F 0000 1010 0000 0000 :status低16位 0000 0000 0111 1111 :0x7F 0000 0000 0000 000 :status&0x7F (status>>8)&0xFF 0000 1010 0000 0000 :status低16位 0000 0000 0000 1010 :status>>8 0000 0000 1111 1111 :0xFF 0000 0000 0000 1010 :(status>>8)&0xFF
验证一下,程序正常终止时,status低16位的高8位是退出码
[BCH@hcss-ecs-6176 10_31]$ cat myprocess.c #include<stdio.h> #include<unistd.h> #include<stdlib.h> void Worker() { int cnt=5; while(cnt--) { printf("I am child process,pid: %d ,ppid :%d,cnt:%d\n",getpid(),getppid(),cnt); sleep(1); } } int main() { pid_t id=fork(); if(id==0) { //child Worker(); exit(1);//这里1是自己定义的,所以子进程的退出码为1时错误的 } else { //father int status=0; printf("wait before\n"); pid_t rid=waitpid(id,&status,0); printf("wait after\n"); if(rid==id) { printf("wait sucess,pid:%d ,rid:%d,status:%d,exit sign:%d,exit code:%d \n",getpid(),rid,status,status&0x7F,(status>>8)&0xFF); } } return 0; } [BCH@hcss-ecs-6176 10_31]$ ./myprocess wait before I am child process,pid: 3504 ,ppid :3503,cnt:4 I am child process,pid: 3504 ,ppid :3503,cnt:3 I am child process,pid: 3504 ,ppid :3503,cnt:2 I am child process,pid: 3504 ,ppid :3503,cnt:1 I am child process,pid: 3504 ,ppid :3503,cnt:0 wait after wait sucess,pid:3503 ,rid:3504,status:256,exit sign:0,exit code:1
验证一下,程序正常终止时,status低16位的高8位是退出码,低八位是退出信号
[BCH@hcss-ecs-6176 10_31]$ cat myprocess.c #include<stdio.h> #include<unistd.h> #include<stdlib.h> void Worker() { int cnt=5; while(cnt--) { printf("I am child process,pid: %d ,ppid :%d,cnt:%d\n",getpid(),getppid(),cnt); sleep(1); int a=10; a/=0; } } int main() { pid_t id=fork(); if(id==0) { //child Worker(); exit(1);//这里1是自己定义的,所以子进程的退出码为1时错误的 } else { //father int status=0; printf("wait before\n"); pid_t rid=waitpid(id,&status,0); printf("wait after\n"); if(rid==id) { printf("wait sucess,pid:%d ,rid:%d,status:%d,exit sign:%d,exit code:%d \n",getpid(),rid,status,status&0x7F,(status>>8)&0xFF); } } return 0; } [BCH@hcss-ecs-6176 10_31]$ ./myprocess wait before I am child process,pid: 9439 ,ppid :9438,cnt:4 wait after wait sucess,pid:9438 ,rid:9439,status:8,exit sign:8,exit code:0//退出信号为8
当一个进程异常了(收到信号),exit code(退出码)还有意义吗?
是没有意义的,所以退出码就不需要关心是多少了
有没有收到信号怎么判定?
只需要判断exit sign是否为0
父进程如何得知子进程的退出信息呢?wait/waitpid(系统调用)
进行位运算太麻烦了,使用os自带函数验证status
WIFEXITED(status): 若为正常终止子进程返回的状态,则为真。(查看进程是否是正常退出) WEXITSTATUS(status): 若WIFEXITED非零,提取子进程退出码。(查看进程的退出码) [BCH@hcss-ecs-6176 10_31]$ cat myprocess.c #include<stdio.h> #include<unistd.h> #include<stdlib.h> void Worker() { int cnt=5; while(cnt--) { printf("I am child process,pid: %d ,ppid :%d,cnt:%d\n",getpid(),getppid(),cnt); sleep(1); } } int main() { pid_t id=fork(); if(id==0) { //child Worker(); exit(1); } else { //father int status=0; printf("wait before\n"); //pid_t rid=wait(NULL); pid_t rid=waitpid(id,&status,0); printf("wait after\n"); if(rid==id) { //printf("wait sucess,pid:%d ,rid:%d,status:%d,exit sign:%d,exit code:%d \n",getpid(),rid,status,status&0x7F,(status>>8)&0xFF); if(WIFEXITED(status)) { printf("child process normal quit,exit code:%d\n",WEXITSTATUS(status)); } else { printf("child process quit except!\n"); } } sleep(10); } return 0; } [BCH@hcss-ecs-6176 10_31]$ ./myprocess wait before I am child process,pid: 28038 ,ppid :28037,cnt:4 I am child process,pid: 28038 ,ppid :28037,cnt:3 I am child process,pid: 28038 ,ppid :28037,cnt:2 I am child process,pid: 28038 ,ppid :28037,cnt:1 I am child process,pid: 28038 ,ppid :28037,cnt:0 wait after child process normal quit,exit code:1
创建多个子进程,通过waitpid等待子进程并回收资源
[BCH@hcss-ecs-6176 10_31]$ cat myprocess.c #include<stdio.h> #include<unistd.h> #include<stdlib.h> void Worker(int i) { int cnt=10; while(cnt--) { printf("I am child:%d process,pid: %d ,ppid :%d,cnt:%d\n",i,getpid(),getppid(),cnt); sleep(1); } } const int n=10;//创建子进程的个数 int main() { int i=0; for(i=0;i<n;i++) { pid_t id=fork(); if(id==0) { Worker(i); exit(i);//每一个子进程的退出码,设置为创建时的编号 } } //如何等待多个进程 for(i=0;i<n;i++) { int status=0; pid_t rid=waitpid(-1,&status,0);//pid 等于-1时,表示任意一个子进程退出 if(rid>0) { printf("wait child : %d success,exit code:%d\n",rid,WEXITSTATUS(status));//查看每一个子进程的退出码 } } return 0; } [BCH@hcss-ecs-6176 10_31]$ ./myprocess I am child:0 process,pid: 3729 ,ppid :3728,cnt:9//红色表示的是子进程的编号 I am child:2 process,pid: 3731 ,ppid :3728,cnt:9 I am child:4 process,pid: 3733 ,ppid :3728,cnt:9 I am child:5 process,pid: 3734 ,ppid :3728,cnt:9 I am child:1 process,pid: 3730 ,ppid :3728,cnt:9 I am child:3 process,pid: 3732 ,ppid :3728,cnt:9 I am child:7 process,pid: 3736 ,ppid :3728,cnt:9 I am child:6 process,pid: 3735 ,ppid :3728,cnt:9 I am child:8 process,pid: 3737 ,ppid :3728,cnt:9 I am child:9 process,pid: 3738 ,ppid :3728,cnt:9 I am child:0 process,pid: 3729 ,ppid :3728,cnt:8 I am child:2 process,pid: 3731 ,ppid :3728,cnt:8 I am child:4 process,pid: 3733 ,ppid :3728,cnt:8 I am child:5 process,pid: 3734 ,ppid :3728,cnt:8 I am child:1 process,pid: 3730 ,ppid :3728,cnt:8 I am child:3 process,pid: 3732 ,ppid :3728,cnt:8 I am child:7 process,pid: 3736 ,ppid :3728,cnt:8 I am child:6 process,pid: 3735 ,ppid :3728,cnt:8 I am child:8 process,pid: 3737 ,ppid :3728,cnt:8 I am child:9 process,pid: 3738 ,ppid :3728,cnt:8 I am child:0 process,pid: 3729 ,ppid :3728,cnt:7 I am child:2 process,pid: 3731 ,ppid :3728,cnt:7 I am child:4 process,pid: 3733 ,ppid :3728,cnt:7 I am child:5 process,pid: 3734 ,ppid :3728,cnt:7 I am child:1 process,pid: 3730 ,ppid :3728,cnt:7 I am child:3 process,pid: 3732 ,ppid :3728,cnt:7 I am child:7 process,pid: 3736 ,ppid :3728,cnt:7 I am child:8 process,pid: 3737 ,ppid :3728,cnt:7 I am child:6 process,pid: 3735 ,ppid :3728,cnt:7 I am child:9 process,pid: 3738 ,ppid :3728,cnt:7 I am child:0 process,pid: 3729 ,ppid :3728,cnt:6 I am child:2 process,pid: 3731 ,ppid :3728,cnt:6 I am child:4 process,pid: 3733 ,ppid :3728,cnt:6 I am child:5 process,pid: 3734 ,ppid :3728,cnt:6 I am child:1 process,pid: 3730 ,ppid :3728,cnt:6 I am child:3 process,pid: 3732 ,ppid :3728,cnt:6 I am child:7 process,pid: 3736 ,ppid :3728,cnt:6 I am child:8 process,pid: 3737 ,ppid :3728,cnt:6 I am child:6 process,pid: 3735 ,ppid :3728,cnt:6 I am child:9 process,pid: 3738 ,ppid :3728,cnt:6 I am child:0 process,pid: 3729 ,ppid :3728,cnt:5 I am child:2 process,pid: 3731 ,ppid :3728,cnt:5 I am child:4 process,pid: 3733 ,ppid :3728,cnt:5 I am child:5 process,pid: 3734 ,ppid :3728,cnt:5 I am child:1 process,pid: 3730 ,ppid :3728,cnt:5 I am child:7 process,pid: 3736 ,ppid :3728,cnt:5 I am child:3 process,pid: 3732 ,ppid :3728,cnt:5 I am child:8 process,pid: 3737 ,ppid :3728,cnt:5 I am child:6 process,pid: 3735 ,ppid :3728,cnt:5 I am child:9 process,pid: 3738 ,ppid :3728,cnt:5 I am child:0 process,pid: 3729 ,ppid :3728,cnt:4 I am child:2 process,pid: 3731 ,ppid :3728,cnt:4 I am child:4 process,pid: 3733 ,ppid :3728,cnt:4 I am child:5 process,pid: 3734 ,ppid :3728,cnt:4 I am child:1 process,pid: 3730 ,ppid :3728,cnt:4 I am child:7 process,pid: 3736 ,ppid :3728,cnt:4 I am child:3 process,pid: 3732 ,ppid :3728,cnt:4 I am child:6 process,pid: 3735 ,ppid :3728,cnt:4 I am child:8 process,pid: 3737 ,ppid :3728,cnt:4 I am child:9 process,pid: 3738 ,ppid :3728,cnt:4 I am child:0 process,pid: 3729 ,ppid :3728,cnt:3 I am child:2 process,pid: 3731 ,ppid :3728,cnt:3 I am child:4 process,pid: 3733 ,ppid :3728,cnt:3 I am child:5 process,pid: 3734 ,ppid :3728,cnt:3 I am child:1 process,pid: 3730 ,ppid :3728,cnt:3 I am child:7 process,pid: 3736 ,ppid :3728,cnt:3 I am child:6 process,pid: 3735 ,ppid :3728,cnt:3 I am child:3 process,pid: 3732 ,ppid :3728,cnt:3 I am child:8 process,pid: 3737 ,ppid :3728,cnt:3 I am child:9 process,pid: 3738 ,ppid :3728,cnt:3 I am child:0 process,pid: 3729 ,ppid :3728,cnt:2 I am child:2 process,pid: 3731 ,ppid :3728,cnt:2 I am child:4 process,pid: 3733 ,ppid :3728,cnt:2 I am child:5 process,pid: 3734 ,ppid :3728,cnt:2 I am child:1 process,pid: 3730 ,ppid :3728,cnt:2 I am child:7 process,pid: 3736 ,ppid :3728,cnt:2 I am child:6 process,pid: 3735 ,ppid :3728,cnt:2 I am child:3 process,pid: 3732 ,ppid :3728,cnt:2 I am child:8 process,pid: 3737 ,ppid :3728,cnt:2 I am child:9 process,pid: 3738 ,ppid :3728,cnt:2 I am child:0 process,pid: 3729 ,ppid :3728,cnt:1 I am child:2 process,pid: 3731 ,ppid :3728,cnt:1 I am child:4 process,pid: 3733 ,ppid :3728,cnt:1 I am child:5 process,pid: 3734 ,ppid :3728,cnt:1 I am child:7 process,pid: 3736 ,ppid :3728,cnt:1 I am child:1 process,pid: 3730 ,ppid :3728,cnt:1 I am child:3 process,pid: 3732 ,ppid :3728,cnt:1 I am child:6 process,pid: 3735 ,ppid :3728,cnt:1 I am child:8 process,pid: 3737 ,ppid :3728,cnt:1 I am child:9 process,pid: 3738 ,ppid :3728,cnt:1 I am child:0 process,pid: 3729 ,ppid :3728,cnt:0 I am child:2 process,pid: 3731 ,ppid :3728,cnt:0 I am child:4 process,pid: 3733 ,ppid :3728,cnt:0 I am child:5 process,pid: 3734 ,ppid :3728,cnt:0 I am child:3 process,pid: 3732 ,ppid :3728,cnt:0 I am child:7 process,pid: 3736 ,ppid :3728,cnt:0 I am child:8 process,pid: 3737 ,ppid :3728,cnt:0 I am child:1 process,pid: 3730 ,ppid :3728,cnt:0 I am child:6 process,pid: 3735 ,ppid :3728,cnt:0 I am child:9 process,pid: 3738 ,ppid :3728,cnt:0 wait child : 3729 success,exit code:0 wait child : 3730 success,exit code:1 wait child : 3731 success,exit code:2 wait child : 3732 success,exit code:3 wait child : 3733 success,exit code:4 wait child : 3734 success,exit code:5 wait child : 3735 success,exit code:6 wait child : 3736 success,exit code:7 wait child : 3737 success,exit code:8 wait child : 3738 success,exit code:9 可以发现子进程并不是按照创建的顺序被调度的
我们为什么不用全局变量获取子进程的退出信息?而用系统调用(WEXITSTATUS(status))
进程具有独立性,父进程无法直接获得子进程的退出信息
waitpid中的options
🌸🌸🌸如果大家还有不懂或者建议都可以发在评论区,我们共同探讨,共同学习,共同进步。谢谢大家! 🌸🌸🌸