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 来执行命令而不是 systemexec 函数用已执行的程序替换进程,从不 returns (除非出现错误)。当执行的程序终止时,进程也会终止。

使用 waitpid(pid, status, option) 明确提及 pid 解决了所有问题。