2009-10-22 13 views
5

Escribo mi propio caparazón de juguete y me encuentro con un bache tratando de implementar el control del trabajo.No Child Process Error de waitpid() al esperar el grupo de proceso

Estoy estableciendo el grupo de procesos del hijo, tanto en el hijo como en el padre con setpgid. Mi llamada de espera es:

Sin embargo, waitpid devuelve -1 y perror dice "Sin proceso hijo". Sin embargo, parece esperar todo el tiempo. Además, la salida ps parece correcta cuando se ejecuta desde el shell. Desde ps el proceso de los padres es kbsh como lo esperaría.

% 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 

¿Alguien ve lo que estoy haciendo mal? puede publicar más código si es necesario ...

+0

parece suceder con -1, así como -pid SIGCHILD –

+0

Fue ignorning, esa es la razón por la que no estaba funcionando :-P –

Respuesta

9

estaba ignorando SIGCHLD, de la página man 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

Gracias por responder a esto, me estaba dirigiendo a esto porque el artículo [aquí] (http://www.gnu.org/software/libc/manual/html_node/Implementing-a-Shell.html#Implementing-a- Shell) parece estar desactualizado. –

2

No es necesario configurar la ID del grupo de procesos. El niño hereda el pid del padre como grupo de forma predeterminada. Cuando esperas, tienes que esperar a que pid del padre:

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-a-Shell - Parece decir que sí. "A medida que se bifurca cada proceso, debe ponerse en el nuevo grupo de procesos al llamar a setpgid" –

+0

Creo que porque los grupos de procesos controlan el primer plano y el fondo. –

2

encontré este hilo al intentar aplicar una pequeña concha para mi curso de informática, y pensé que compartiría lo que funcionó para mí. Que estaba recibiendo el siguiente error:

Waitpid error: No child processes 

En mi caso, yo estaba usando una envoltura proporcionada por los sistemas informáticos: Perspectiva de libros de texto de un desarrollador. Para arreglar mi error, he cambiado Waitpid en csapp.c de

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

a

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