我在学校学习C和Linux。我的任务是创建一个父进程,它创建3个子进程。所创建的子进程不应有更多的子进程。我必须证明所有进程同时存在。此后,父进程应等待所创建子进程的终止
这是我的代码:
#包括<;系统/类型h>;
#包括<;unistd.h>;
#包括<;标准h>;
#包括<;stdlib.h>;
#包括<;sys/wait.h>;
int main(){
int i;
int-var=0;
printf(“我是家长,我的ID:%d\n”,getpid());
对于(i=0;i<;3;i++){
如果(var==0){
如果(fork()==0){
var++;
printf(“子:PID:%d;PPID:%d\n”,getpid(),getppid());
printf(“变量:%d\n”,变量);
}
}
}
睡眠(3);
智力状态;
等待(状态);
printf(“d说再见!\n”,getpid());
}
我的输出:
我是家长,我的ID:273
儿童:PID:274;PPID:273
变量:1
儿童:PID:275;PPID:273
变量:1
儿童:PID:276;PPID:273
变量:1
我还尝试了打印出来的WEXITSTATUS(),但这只是父进程,他用0表示
此代码创建一个父进程及其3个子进程,但不包括其他子进程。但我如何让父进程等待3个子进程终止,如何证明所有进程可以同时存在
让我们从当前代码的错误开始:
-
在需要时显式终止子代码,并不是分离父/子代码。代码中的每个子级将继续执行
for循环,然后在执行wait()后执行代码,该循环应仅由父级执行 -
你不是在等所有的孩子。如果创建3个子项,则需要进行3个
wait()调用,每个子项调用一个。在您的情况下,顺序实际上并不重要,因此您可以使用wait()而不是waitpid()/wait3()/wait4(),但您需要另一个循环 -
您没有检查所使用的任何函数的错误。你绝对应该
-
我有点忽略了
var变量的要点,如果只是为了避免在子代码中进入循环体,那么简单的break,exit()或return就足够了
代码的正确版本如下所示:
\include<;unistd.h>;
#包括<;标准h>;
#包括<;stdlib.h>;
#包括<;sys/wait.h>;
#包括<;系统/类型h>;
int main(){
未签名的i;
智力状态;
pid_t child_pid;
printf(“我是家长,我的PID:%d\n”,getpid());
对于(i=0;i<;3;i++){
child_pid=fork();
如果(子项pid==-1){
perror(“fork()失败”);
返回1;
}else if(子项pid==0){
printf(“子:PID:%d;PPID:%d\n”,getpid(),getppid());
睡眠(3);
printf(“孩子%d说再见!\n”,getpid());
返回0;
}
}
对于(i=0;i<;3;i++){
child_pid=等待(&;状态);
如果(子项pid==-1){
perror(“wait()失败”);
返回1;
}
如果(妻子退出(状态)){
printf(“子%d已退出,代码为%d\n”,子pid,WEXITSTATUS(状态));
}否则{
//在这里处理其他情况,如WIFSIGNALED、WIFSTOPPED等。。。
//有关更多信息,请参见'man 2 wait'。
}
}
返回0;
}
我如何证明所有流程可以同时存在
这可以通过很多不同的方式来实现。您可以在另一个终端上通过使用类似于ps的程序在3个孩子出生后从外部执行此操作(可能会将睡眠时间增加到10秒以获得更多时间):
$ps--ppid 249626#从程序的输出中获取此信息
PID TTY时间指令
249627分/1 00:00:00测试
249628分/1 00:00:00测试
249629 pts/1 00:00:00测试
或者,您可以通过在子代码中打印程序内执行的开始和结束时间来完成此操作:
\include<;unistd.h>;
#包括<;标准h>;
#包括<;stdlib.h>;
#包括<;sys/wait.h>;
#包括<;系统/类型h>;
#包括<;时间;
作废打印时间(作废){
时间;
struct tm*本地;
const char*local_str;
t=时间(空);
如果(t==(时间t)-1){
perror(“time()失败”);
回来
}
本地=本地时间(&;t)
if(local==NULL){
perror(“localtime()失败”);
回来
}
local_str=asctime(&;local);
if(local_str==NULL){
perror(“asctime()失败”);
回来
}
ptintf(“子%d时间:%s\n”,getpid(),local_str);
}
// ... 和以前一样的代码。。。
}else if(子项pid==0){
printf(“子%d PPID:%d\n”,getpid(),getppid());
打印时间();
睡眠(3);
printf(“孩子%d说再见!\n”,getpid());
打印时间();
返回0;
}
// ... 和以前一样的代码。。。
输出:
我是家长,我的PID:250469
儿童250470 PPID:250469
儿童250471 PPID:250469
儿童250470时间:周二10月26日23:53:03 2021
儿童250472 PPID:250469
儿童250471时间:周二10月26日23:53:03 2021
儿童250472时间:周二10月26日23:53:03 2021
孩子250470说再见!
儿童250470时间:周二10月26日23:53:06 2021
孩子说再见!
儿童250471时间:周二10月26日23:53:06 2021
孩子250472说再见!
儿童250472时间:周二10月26日23:53:06 2021
子250470已退出,代码为0
子250471已退出,代码为0
子250472已退出,代码为0