Ошибка дочернего процесса от waitpid () при ожидании группы процессов - PullRequest
6 голосов
/ 22 октября 2009

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

Я устанавливаю группу процессов дочернего процесса как в дочернем, так и в родительском процессах с помощью setpgid. Мой звонок ожидания:

pid = waitpid(-pid, &status, 0)

Однако waitpid возвращает -1, а perror говорит: «Нет дочернего процесса». Тем не менее, кажется, каждый раз ждать. Кроме того, вывод ps выглядит правильно, когда запускается из оболочки. Поскольку процесс ps parent является kbsh, как я и ожидал.

% ps -o pid,ppid,pgrp,session,tpgid,comm
Forking
In Parent: Setting process group to 20809 of process 20809 with setpgid
In Child Processes, pid of child process is 20809
in Child: Setting process group to 20809 of process 20809 with setpgid
Requesting that Process Group 20809 becomes the foreground process with tcsetpgrp
Waiting for job with process group 20809
  PID  PPID  PGRP  SESS TPGID COMMAND
12002 32573 12002 12002 20809 zsh
20808 12002 20808 12002 20809 kbsh
20809 20808 20809 12002 20809 ps
Wait Error: No child processes
Restoring Shell process group 20808 to forground

Кто-нибудь видит, что я делаю не так? может разместить больше кода, если это необходимо ...

Ответы [ 3 ]

13 голосов
/ 22 октября 2009

Я игнорировал sigchld со страницы руководства waitpid:

POSIX.1-2001 указывает, что если расположение SIGCHLD установлено на SIG_IGN или флаг SA_NOCLDWAIT установить для SIGCHLD (см. sigaction (2)), тогда дети, которые заканчивают, не стать зомби и вызов ждать () или waitpid () будет блокировать, пока все дети прекратились, а потом ошибка с errno, установленным в ECHILD. ( оригинальный стандарт POSIX оставил поведение установки SIGCHLD в SIG_IGN не указано.) Linux 2.6 соответствует этой спецификации. Однако Linux 2.4 (и более ранние версии) нет: если вызов wait () или waitpid () сделано в то время как SIGCHLD игнорируется, вызов ведет себя так, как будто SIGCHLD не были проигнорированы, что есть, блокировка вызова до следующего ребенок завершает и затем возвращает идентификатор процесса и статус этого потомка.

2 голосов
/ 13 марта 2015

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

Waitpid error: No child processes

В моем случае я использовал оболочку, предоставленную компьютерными системами: Учебник по программированию. Чтобы исправить мою ошибку, я изменил Waitpid в csapp.c с

pid_t Waitpid(pid_t pid, int *iptr, int options) 
{
    pid_t retpid;

    if ((retpid  = waitpid(pid, iptr, options)) < 0) 
        unix_error("Waitpid error");
    return(retpid);
}

до

pid_t Waitpid(pid_t pid, int *iptr, int options)
{
        pid_t retpid;

        retpid  = waitpid(pid, iptr, options);
        if (retpid < 0 && errno != ECHILD)
                unix_error("Waitpid error");
        return(retpid);
}
2 голосов
/ 22 октября 2009

Вам не нужно устанавливать идентификатор группы процессов. Ребенок наследует pid родителя как группу по умолчанию. Когда вы ждете, вам нужно дождаться pid родителя:

int main(int argc, char **argv)
{
    pid_t pid;
    int stat;

    if ((pid = fork()))
    {
        printf("PARENT: %d | CHILD: %d\n", getpid(), pid);
        waitpid(-getpid(), &stat, 0);
        printf("DONE: %m\n");
    }
    else
    {
        printf("CHILD: %d\n", getpid());
        sleep(3);
    }
    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...