wait(NULL) 不会等到分叉进程完成
wait(NULL) is not waiting till forked process is finished
这是使用 system() 在 child 进程中执行命令的函数。但是一旦命令完成执行,它就会停止。然而,在 运行 ps 命令中,我发现了新的 a.out 进程 运行。该程序应该等待 child 完成。
void execute(char **argv)
{
if(fork() == 0)
{
if (argv[1] == NULL)
{
system(argv[0]);
}
else
{
char tmp[1024] ;
*(tmp+0) = '[=10=]';
strcat(tmp,*argv++);
while(*argv !=NULL)
{
strcat(tmp," ");
strcat(tmp,*argv++);
}
system(tmp);
}
}
else
{
printf("\nWaiting\n");
wait(0);
printf("\nWaiting Complete\n");
}
}
下面的输出就是这种
SillyShell> ps
Waiting
PID TTY TIME CMD
7520 tty2 00:00:00 bash
7919 tty2 00:00:00 a.out
7923 tty2 00:00:00 a.out
7926 tty2 00:00:00 a.out
7927 tty2 00:00:00 sh
7928 tty2 00:00:00 ps
SillyShell>
这是作为解决方案之一的编辑代码。一旦使用带有“&”的命令,再次等待 stops 等待任何进程
void execute(char **argv)
{
pid_t pid;
int countArg = 0;
char** tmp = argv;
while(*argv !=NULL)
{
*argv++;
countArg++;
}
argv = tmp;
//printf("%s",argv[countArg-1]);
int flg = 0;
if(strcmp(argv[countArg-1], "&") == 0)
{
//printf("Running in Background\n");
flg = 1;
argv[countArg-1] = NULL;
}
if((pid=fork()) < 0)
{
printf("Could not create child process");
exit(1);
}
else if(pid == 0)
{
if (execvp(*argv, argv) < 0)
{
printf("Could not execute command");
exit(2);
}
else
{
if(flg==1)
exit(0);
}
}
else
{
if(flg == 1)
{
printf("PID=%d Running in background\n",pid);
flg=0;
fflush(stdin);
return;
}
else
{
printf("Waiting %s %d",*argv,pid);
wait(NULL);
printf("--wait complete");
}
}
}
输出
Waiting clear 6532--wait completeSillyShell> ls
a.out blockchain key.pem task1.c task3.c wait.c
bash fork.c OpenMP task2.c task4.c
Waiting ls 6535--wait completeSillyShell> ps &
PID=6537 Running in background
SillyShell> PID TTY TIME CMD
6406 pts/1 00:00:00 bash
6531 pts/1 00:00:00 a.out
6537 pts/1 00:00:00 ps
SillyShell> ps
Waiting ps 6538--wait completeSillyShell> PID TTY TIME CMD
6406 pts/1 00:00:00 bash
6531 pts/1 00:00:00 a.out
6538 pts/1 00:00:00 ps
您的子进程永远不会 退出! 当 system
函数完成后,子进程将继续。您需要明确地 exit
它。
或者像大多数类似 shell 的实现一样使用 the exec
family of function 来执行命令而不是 system
。 exec
函数用已执行的程序替换进程,从不 returns (除非出现错误)。当执行的程序终止时,进程也会终止。
使用 waitpid(pid, status, option) 明确提及 pid 解决了所有问题。
这是使用 system() 在 child 进程中执行命令的函数。但是一旦命令完成执行,它就会停止。然而,在 运行 ps 命令中,我发现了新的 a.out 进程 运行。该程序应该等待 child 完成。
void execute(char **argv)
{
if(fork() == 0)
{
if (argv[1] == NULL)
{
system(argv[0]);
}
else
{
char tmp[1024] ;
*(tmp+0) = '[=10=]';
strcat(tmp,*argv++);
while(*argv !=NULL)
{
strcat(tmp," ");
strcat(tmp,*argv++);
}
system(tmp);
}
}
else
{
printf("\nWaiting\n");
wait(0);
printf("\nWaiting Complete\n");
}
}
下面的输出就是这种
SillyShell> ps
Waiting
PID TTY TIME CMD
7520 tty2 00:00:00 bash
7919 tty2 00:00:00 a.out
7923 tty2 00:00:00 a.out
7926 tty2 00:00:00 a.out
7927 tty2 00:00:00 sh
7928 tty2 00:00:00 ps
SillyShell>
这是作为解决方案之一的编辑代码。一旦使用带有“&”的命令,再次等待 stops 等待任何进程
void execute(char **argv)
{
pid_t pid;
int countArg = 0;
char** tmp = argv;
while(*argv !=NULL)
{
*argv++;
countArg++;
}
argv = tmp;
//printf("%s",argv[countArg-1]);
int flg = 0;
if(strcmp(argv[countArg-1], "&") == 0)
{
//printf("Running in Background\n");
flg = 1;
argv[countArg-1] = NULL;
}
if((pid=fork()) < 0)
{
printf("Could not create child process");
exit(1);
}
else if(pid == 0)
{
if (execvp(*argv, argv) < 0)
{
printf("Could not execute command");
exit(2);
}
else
{
if(flg==1)
exit(0);
}
}
else
{
if(flg == 1)
{
printf("PID=%d Running in background\n",pid);
flg=0;
fflush(stdin);
return;
}
else
{
printf("Waiting %s %d",*argv,pid);
wait(NULL);
printf("--wait complete");
}
}
}
输出
Waiting clear 6532--wait completeSillyShell> ls
a.out blockchain key.pem task1.c task3.c wait.c
bash fork.c OpenMP task2.c task4.c
Waiting ls 6535--wait completeSillyShell> ps &
PID=6537 Running in background
SillyShell> PID TTY TIME CMD
6406 pts/1 00:00:00 bash
6531 pts/1 00:00:00 a.out
6537 pts/1 00:00:00 ps
SillyShell> ps
Waiting ps 6538--wait completeSillyShell> PID TTY TIME CMD
6406 pts/1 00:00:00 bash
6531 pts/1 00:00:00 a.out
6538 pts/1 00:00:00 ps
您的子进程永远不会 退出! 当 system
函数完成后,子进程将继续。您需要明确地 exit
它。
或者像大多数类似 shell 的实现一样使用 the exec
family of function 来执行命令而不是 system
。 exec
函数用已执行的程序替换进程,从不 returns (除非出现错误)。当执行的程序终止时,进程也会终止。
使用 waitpid(pid, status, option) 明确提及 pid 解决了所有问题。