Linux 第二十章

news/2024/12/22 13:07:31/

🐶博主主页:@ᰔᩚ. 一怀明月ꦿ 

❤️‍🔥专栏系列:线性代数,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!”);\\没有\nsleep(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){//childWorker();exit(0);}else{sleep(10);//fatherpid_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 ./myprocess2676  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 ./myprocess2676  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 ./myprocess2676  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 ./myprocess2676  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 ./myprocess2676  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 ./myprocess2676  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 ./myprocess2676  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 ./myprocess2676  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 ./myprocess2676  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 ./myprocess2676  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){//childWorker();exit(10);}else{//fatherint 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的10status是一个整数,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){//childWorker();exit(10);//这里10是自己定义的,所以子进程的退出码为10时时正确的}else{//fatherint 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:10status&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){//childWorker();exit(1);//这里1是自己定义的,所以子进程的退出码为1时错误的}else{//fatherint 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){//childWorker();exit(1);//这里1是自己定义的,所以子进程的退出码为1时错误的}else{//fatherint 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){//childWorker();exit(1);}else{//fatherint 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

  🌸🌸🌸如果大家还有不懂或者建议都可以发在评论区,我们共同探讨,共同学习,共同进步。谢谢大家! 🌸🌸🌸 


http://www.ppmy.cn/news/1455940.html

相关文章

PHP 框架安全:ThinkPHP 序列 漏洞测试.

什么是 ThinkPHP 框架. ThinkPHP 是一个流行的国内 PHP 框架&#xff0c;它提供了一套完整的安全措施来帮助开发者构建安全可靠的 web 应用程序。ThinkPHP 本身不断更新和改进&#xff0c;以应对新的安全威胁和漏洞。 ThinkPHP 框架的安全特性&#xff1a; (1) 输入过滤和验证…

基于FPGA的去雾算法

去雾算法的原理是基于图像去模糊的原理&#xff0c;通过对图像中的散射光进行估计和去除来消除图像中的雾霾效果。 去雾算法通常分为以下几个步骤&#xff1a; 1. 导引滤波&#xff1a;首先使用导引滤波器对图像进行滤波&#xff0c;目的是估计图像中散射光的强度。导引滤波器…

(论文阅读-优化器)Selectivity Estimation using Probabilistic Models

目录 摘要 一、简介 二、单表估计 2.1 条件独立Condition Independence 2.2 贝叶斯网络Bayesian Networks 2.3 查询评估中的贝叶斯网络 三、Join选择性估计 3.1 两表Join 3.2 概率关系模型 3.3 使用PRMs的选择性估计 四、PRM构建 4.1 评分标准 4.2 参数估计 4.3 结…

uniapp文本框上下滚动问题

一个基本需求&#xff0c;textarea标签没有办法通过手拖动的方式进行滚动&#xff0c;当文字超出其容量后&#xff0c;想要编辑上面被遮挡部分的文字这边难以点到&#xff0c;电脑可以鼠标滚轮&#xff0c;但手机需要拖动但无效&#xff1a; 下面提供了我的解决思路&#xff1a…

IP路由:构建高效网络的基石

目录 前言 一. IP数据报交付 二. IP路由 1.IP路由器 2.IP路由表 3.特定主机路由与默认路由 4.路由解析 5.路由选择过程 三. 路由协议 1.静态路由与动态路由 2.内部网关协议与外部网关协议 3.距离向量路由协议和链路状态路由协议 四. RIP协议 1.概述 2.工作原理 3.报文格式 …

vue2中的 <keep-alive>

在 Vue 2 中&#xff0c;给组件加上 name 属性本身并不直接实现切换路由时保存数据的功能。然而&#xff0c;name 属性在 Vue 组件中确实有一些用途&#xff0c;特别是在与 <keep-alive> 组件和 Vue 开发者工具&#xff08;vue-devtools&#xff09;一起使用时。 关于路…

X 推出 Stories 功能,由 Grok AI 生成新闻摘要

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

深度学习学习日记(5.6)

在 ViT&#xff08;Vision Transformer&#xff09;模型中&#xff0c;输入图像被分割成固定大小的图块&#xff0c;然后通过一个线性变换&#xff08;通常是一个卷积层&#xff09;来将每个图块投影到一个较低维度的特征空间。这些投影后的图块被视为序列&#xff0c;然后输入…