这是使用system()在子进程中执行命令的功能。但是,一旦命令完成执行,它将停止。但是,在运行ps命令时,我发现新的a.out进程正在运行。该程序原本应该等待孩子完成。
void execute(char **argv)
{
if(fork() == 0)
{
if (argv[1] == NULL)
{
system(argv[0]);
}
else
{
char tmp[1024] ;
*(tmp+0) = '\0';
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>
这是作为解决方案之一而编辑的代码。一旦使用带有“&”的命令,此后再次等待将停止等待任何进程
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
答案 0 :(得分:1)
您的子进程永远不会退出!完成system
函数后,子进程将继续运行。您需要明确exit
。
或者像大多数类似shell的实现那样做,并使用the exec
family of function而不是system
来执行命令。 exec
函数用执行的程序替换该进程,并且永不返回(除非有错误)。当执行的程序终止时,该过程也会终止。
答案 1 :(得分:0)
使用waitpid(pid,状态,选项)明确提及pid可以解决所有问题。