C - псевдооболочка и параллелизм - PullRequest
0 голосов
/ 13 октября 2010

Я пишу программу псевдооболочки, которая создает дочерний процесс из родительского процесса. Родительский процесс ожидает завершения дочернего процесса, прежде чем продолжить. Мой код разветвления выглядит примерно так:

if(fork()==0)
{
     execvp(cmd, args);
}
else
{
     int status = 0;
     wait(&status);
     printf("Child exited with status of %d\n", status);
}

Но я хочу иметь возможность анализировать оператор '&', чтобы, если пользователь вводит его в конце командной строки, родитель не ждал дочернего элемента, прежде чем предложить пользователю другую команду. Я добавил немного кода, чтобы справиться с этим, но я не был точно уверен, работает ли он правильно. Будет ли это выглядеть примерно так:

if(fork()==0)
{
    execvp(cmd, args);
}
else
{
    if(andOp = 1) //boolean to keep track of if '&' was encountered in parsing
    {
        shellFunc();   //main function to prompt user for a cmd line
    }
    int status = 0;
    wait(&status);
    printf("Child exited with status of %d\n", status);
}

Достигает ли это на самом деле параллелизма, достигаемого обычной оболочкой?

Ответы [ 2 ]

2 голосов
/ 13 октября 2010

Остерегайтесь назначения вместо сравнения.

Остерегайтесь неудачного выполнения команды - exit(1); после execvp().

Я думаю, я бы использовал:

if (andOp == 0)
{
     int status;
     int corpse = wait(&status);
     printf("Child %d exited with status 0x%04X\n", corpse, status);
}

То есть, я бы только подождал, если бы отсутствовал '&'.

Однако, когда фоновые дети умирают случайным образом, вам нужно отслеживать фоновые процессы, и, в частности, вам нужно выполнить циклна wait() до тех пор, пока ребенок, которого вы только что разбудили, не умрет.Поэтому вам также нужно отловить этот PID из fork().

. Возможно, вы захотите получить фантазию и использовать waitpid() после сбора ожидаемого ребенка, чтобы очистить любые другие тела, используя-блокирующий параметр, чтобы, если таких детей не было, он сразу возвращается.Вы по-прежнему будете использовать его в цикле, так что, если все 6 фоновых заданий завершены, вы соберете их все.

В качестве альтернативы, вы можете рассмотреть возможность игнорирования сигналов «смерти ребенка» (SIGCHLD) - и позволитьсистема позаботится о них.Однако оболочка обычно сообщает о завершении одного из фоновых заданий.

0 голосов
/ 13 октября 2010

Пара проблем:

  • Что делать, если exec не удается?
    • Ты должен убить ребенка
  • Что делать, если сигнал происходит в родительском?
    • ждать, выйдет. Вы должны обнаружить и повторно подождать.
  • Вызов ShellFunc () рекурсивно не помогает, так как нет реальной стратегии выхода.
    • используйте int sigaction () для обнаружения дочерних сбоев в фоновых задачах.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...