wait (NULL) не ждет, пока не завершится разветвленный процесс - PullRequest
0 голосов
/ 04 декабря 2018

Это функция, которая выполняет команды в дочернем процессе с помощью 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 голосов
/ 05 декабря 2018

Явное упоминание pid с использованием waitpid (pid, status, option) решило все проблемы.

0 голосов
/ 04 декабря 2018

Ваш дочерний процесс никогда не завершает работу! Когда функция system завершена, тогда дочерний процесс просто продолжится.Вам необходимо явно exit it.

Или сделать, как это делают большинство реализаций, подобных оболочке, и использовать семейство exec функции для выполнения команды вместо system.Функции exec заменяют процесс исполняемой программой и никогда не возвращаются (если нет ошибки).Когда исполняемая программа завершается, это также завершает процесс.

...