2012-04-15 9 views
8

Ich schreibe ein mapreduce-Programm, das mehrere I/O-Pipes (eine Pipe pro Prozess) verwendet, um einige Endergebnisse zu erhalten. Ich habe ein Problem mit der Erstellung der Prozesse. Genauer gesagt, ich die folgende Fehlermeldung erhalten:fork() - mehrere Prozesse und Systemaufrufe

wait error: Interrupted system call 

Dies ist mein Code, der Prozesse laicht:

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

Danach Ich erstelle einen Thread

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

Die threadFunction select verwendet () Funktion, um herauszufinden, welcher Dateideskriptor zum Lesen bereit ist und liest ihn und legt Daten in einem Wörterbuch ab.

Wenn Form GDB-Debugger ausgeführt wird, das Programm Ausgabe:

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 

Ich weiß nicht, wie das Problem zu beheben. Irgendwelche Vorschläge?

Danke!

Antwort

9

Sie müssen Ihren wait() Aufruf in eine Schleife setzen und wenn es einen Fehler (-1) und errno == EINTR zurückgibt, die Schleife fortsetzen. Jeder andere Fehler ist ein echter Fehler und sollte als solcher behandelt werden.

Dinge wie Profilierungs Timer können Signale dazu führen, den Prozess, das Signal jedoch wahrscheinlich gesendet werden soll, um die Unterbrechung verursacht SIGCHLD, die, wie Sie wissen, wird aufgerufen, wenn ein Kind Prozess Zustand ändert.

EDIT: OK, ich werde die Antwort im Code schreiben:

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

Ich bin nicht sicher, was du meinst. Bitte erläutern. – Krzysiek

+1

@Rafcio Ich habe meine Antwort aktualisiert. – trojanfoe

+1

Danke. Es macht Sinn! :) – Krzysiek