2009-10-22 14 views
5

Pisanie własnej powłoki zabawki i wystąpienie bumpa próbującego zaimplementować kontrolę zadań.Brak błędu procesu potomnego z waitpid() podczas oczekiwania na grupę procesów

Ustawiam grupę procesową dziecka, zarówno w potomstwie, jak i rodzicu, za pomocą setpgid. Moje połączenie oczekujące to:

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

Jednak waitpid zwraca -1, a perror mówi "Brak procesu potomnego". Jednak wydaje się, że za każdym razem czeka. Również wyjście ps wygląda tak, jakby było uruchamiane z powłoki. Ponieważ proces rodzica ps jest kbsh, jak bym się spodziewał.

% 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 

Ktoś widzi, co robię źle? może dodać więcej kodu, jeśli trzeba ...

+0

wydaje się stało z -1, a także -pid –

+0

Czy ignorning SIGCHILD, że jest powód, to nie działa :-P –

Odpowiedz

9

byłem ignorowanie SIGCHLD, ze strony człowieka waitpid:

POSIX.1-2001 specifies that if the disposition of SIGCHLD is set to SIG_IGN or the SA_NOCLDWAIT flag is set for SIGCHLD (see sigaction(2)), then children that terminate do not become zombies and a call to wait() or waitpid() will block until all children have terminated, and then fail with errno set to ECHILD. (The original POSIX standard left the behaviour of setting SIGCHLD to SIG_IGN unspecified.) Linux 2.6 conforms to this specification. However, Linux 2.4 (and earlier) does not: if a wait() or waitpid() call is made while SIGCHLD is being ignored, the call behaves just as though SIGCHLD were not being ignored, that is, the call blocks until the next child terminates and then returns the process ID and status of that child.

+0

Dziękuję za odpowiedź, odkładałem na to uwagę od czasu artykułu [tutaj] (http://www.gnu.org/software/libc/manual/html_node/Implementing-a-Shell.html#Implementing-a- Shell) wydaje się być przestarzałe. –

2

Nie musisz ustawiać ID grupy procesów. Dziecko domyślnie dziedziczy pid rodzica jako grupę. Po czekać, trzeba czekać na PID rodzica:

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; 
} 
+0

http://www.gnu.org/s/libc/manual/html_node/Implementing-a-Shell.html#Implementing-- Shell - Wydaje się, że to robię. "Ponieważ każdy proces jest rozwidlony, powinien umieścić się w nowej grupie procesów, wywołując setpgid" –

+0

Myślę, że ponieważ grupy procesów są kontrolowane przez pierwszy plan i tło. –

2

znalazłem ten wątek, starając się realizować niewielką muszlę na mój kurs informatyki i doszedłem do wniosku, że będę pracował dla mnie. Ja otrzymuję następujący błąd:

Waitpid error: No child processes 

W moim przypadku był przy użyciu opakowanie dostarczone przez systemy komputerowe: Programisty Perspektywa podręcznikowo. Aby naprawić mój błąd, zmieniłem Waitpid w csapp.c z

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); 
} 

do

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); 
} 
Powiązane problemy