fork () - родительский процесс работает без ожидания дочернего процесса - PullRequest
0 голосов
/ 29 сентября 2018

Я делаю оболочку на C для школьного проекта, которая способна запускать процессы параллельно, если ему это приказано.

Это цикл приложения оболочки, который ожидает команды:

while (1) {
    action = parseShellArgs();

    if (action == 1) {
        printf("Exiting...\n");
        break;
    } else if (action == 0) {
        int pid = fork();

        if (pid < 0) {
            printf("Failed to fork\n");
        } else if (pid == 0) {
            (*NUM_PROCESSES_RUNNING)++;
            printf("There are %d processes running\n", *NUM_PROCESSES_RUNNING);
            char * solverArgs[] = {"a", shellArgs[1], NULL};    // first element is placeholder for argv[0]
            execv("CircuitRouter-SeqSolver", solverArgs);
            exit(0);
        } else if (pid > 0) {
            if (*NUM_PROCESSES_RUNNING >= MAXCHILDREN) {
                printf("All processes are busy\n");
                continue;
            }
            int status, childpid;

            wait(&status);
            childpid = WEXITSTATUS(status);
            (*NUM_PROCESSES_RUNNING)--;
            printf("There are %d processes running\n", *NUM_PROCESSES_RUNNING);
            (void)childpid;     // suppress "unused variable" warning
        } else {
            printf("Wait what\n");
        }
    } else {
        printf("Oops, bad input\n");
    }
}

Пожалуйста, не обращайте внимания на увеличивающиеся и уменьшающиеся константы.

Теперь это работает только частично.Всякий раз, когда я даю ему команду для создания другого процесса и запуска другой программы (условное действие == 0, это было проверено и работает), происходит форк и программа выполняется правильно.

Однако я не могу форкмногократно.Под этим я подразумеваю следующее: программа разветвляется, и ребенок исполняет, как указано в вызове execv.Проблема в том, что вместо того, чтобы родительский процесс затем возвращается к ожиданию ввода, возможно, снова разветвляется, он ожидает завершения дочернего процесса.

То, что я пытаюсь сделать в этом цикле, - это чтобы родитель всегдаожидайте ввода и разветвления как приказано, имея несколько детей в случае необходимости.Но, как я объяснил выше, родитель «застревает» в ожидании окончания одного ребенка и только потом возобновляет деятельность.

Заранее спасибо.

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

1 Ответ

0 голосов
/ 29 сентября 2018

С man wait.2

Системный вызов wait () приостанавливает выполнение вызывающего процесса до тех пор, пока не завершится один из его дочерних элементов.

Ваша программа зависаетчто делает waitИспользуйте waitpid вместо этого с WNOHANG.

waitpid(pid_child, &status, WNOHANG);

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

...