wait(NULL)不等待分叉过程完成

时间:2018-12-04 04:12:40

标签: c linux fork wait waitpid

这是使用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

2 个答案:

答案 0 :(得分:1)

您的子进程永远不会退出!完成system函数后,子进程将继续运行。您需要明确exit

或者像大多数类似shell的实现那样做,并使用the exec family of function而不是system来执行命令。 exec函数用执行的程序替换该进程,并且永不返回(除非有错误)。当执行的程序终止时,该过程也会终止。

答案 1 :(得分:0)

使用waitpid(pid,状态,选项)明确提及pid可以解决所有问题。