2012-04-15 14 views
8

Estoy escribiendo un programa mapreduce que usa múltiples tuberías de E/S (una tubería por proceso) para obtener algunos resultados finales. Tengo un problema con la creación de los procesos. En concreto, estoy consiguiendo el error siguiente:fork() - múltiples procesos y llamadas al sistema

wait error: Interrupted system call 

Este es mi código que genera procesos:

while (values[inc]!=NULL) //provided array of text lines 
{ 
    if ((pid = fork()) == -1) { 
     perror("fork error"); 
     exit(EXIT_FAILURE); 
    }  

    else if (pid == 0) {    /* start of child process  */ 
     printf("Child process...\n"); 
     /* pipes[inc][1] is a file descriptor to which myMap writes some data 
      using the write() system call 
      mr is a struct that holds other function pointers */ 
     mr->myMap(pipes[inc][1],values[inc]); 
     exit(0); 
    } 
    else {       /* start of parent process  */ 
     printf("Parent process...\n"); 

     if ((wpid = wait(&status)) == -1) 
     /* Wait for child process.  */ 
      perror("wait error"); 
     else {      /* Check status.    */ 
      if (WIFSIGNALED(status) != 0) 
       printf("Child process ended because of signal %d\n", 
         WTERMSIG(status)); 
      else if (WIFEXITED(status) != 0) 
       printf("Child process ended normally; status = %d\n", 
         WEXITSTATUS(status)); 
      else 
       printf("Child process did not end normally\n"); 
     } 
     //close(fd[1]); 

     printf("Parent process ended\n"); 
    } 
    inc++; 
} 

Después de esto estoy creando un hilo

pthread_t newThread; 
pthread_create(&newThread,NULL,threadFunction,values); 
pthread_join(newThread,NULL); 

El threadFunction utiliza seleccione () funcionan para descubrir qué descriptor de archivo está listo para leerse, lo lee y coloca datos en un diccionario.

Cuando se ejecuta el depurador GDB forma, la salida del programa:

Parent process... 
Child process... 
wait error: Interrupted system call 
Parent process ended 
Parent process... 
Child process ended normally; status = 0 
Parent process ended 
Parent process... 
Child process... 
Child process... 
wait error: Interrupted system call 
Parent process ended 

No sé cómo resolver el problema. ¿Alguna sugerencia?

Gracias!

Respuesta

9

Debe poner su llamada wait() en un bucle y si devuelve un error (-1) y errno == EINTR continúe el ciclo. Cualquier otro error es un error real y debe tratarse como tal.

Cosas como temporizadores de perfiles pueden causar señales que se envían al proceso, sin embargo, probablemente la señal causando la interrupción es SIGCHLD, que como se sabe se llama cuando un proceso hijo cambia de estado.

EDIT: OK, voy a escribir la respuesta en código:

do 
{ 
    wpid = wait(&status); 
} 
while (wpid == -1 && errno == EINTR); 
if (wpid == -1) 
{ 
    perror("wait error"); 
    return -1; 
} 
else 
{ 
    // we have wait status 
    ... 
} 
+0

No estoy seguro de lo que quiere decir. Por favor elabora. – Krzysiek

+1

@Rafcio He actualizado mi respuesta. – trojanfoe

+1

Gracias. ¡Que tiene sentido! :) – Krzysiek

Cuestiones relacionadas