2017-08-16 1 views
0

Wenn ich das in gdb ausführen hängt die Eltern bei waitpid, und ich bin mir nicht sicher warum. Der Elternteil soll Argumente von argv übernehmen und über eine Pipe an das Kind senden. Dann soll der Elternteil die Summe der Argumente vom Kind über seine Rückkehr erhalten. Nicht sicher, warum es das macht.Elternprozess hängt nach dem Aufruf von waitpid

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <sys/wait.h> 
#include <sys/poll.h> 

static int myPipe[2]; 

int main(int argc, char **argv) 
{ 
    pid_t pid; 
    int value; 
    int status; 
    // set up pipe 

    if(pipe(myPipe)) 
    { 
     printf("pipe error\n"); 
     return -1; 
    } 

    // call fork() 
    printf("CS201 - Assignment 3 Premium - I. Forgot\n"); 
    pid = fork(); 
    if (pid == 0) { 
     // -- running in child process -- 
     int  sum = 0; 
     close(myPipe[1]); 

     for(int i = argc; i > 1; i--) 
     { 
      read(myPipe[0], &value, sizeof(value)); 
      sum += value; 
     } 

     // Return sum of numbers. 
     return sum; 
     } 
    else { 
     // -- running in parent process -- 
     int sum = 0; 
     close(myPipe[0]); 

for(int i = argc; i > 1; i--) 
     { 
      value = atoi(argv[i-1]); 
      write(myPipe[0], &value, sizeof(value)); 
     } 
     waitpid(pid, &status, 0); 
     sum = status; 

     printf("sum = %d\n", sum); 
     return 0; 
     } 

Antwort

1

Sie Problem ist, dass in der übergeordneten, Sie sorgfältig schließen myPipe[0] und dann auf mysteriöse Weise, um es anstelle des noch offenen myPipe[1] zu schreiben entscheiden. Wenn Sie bei Ihren Systemaufrufen einen Fehler festgestellt haben, wissen Sie, dass Sie keine Daten an das untergeordnete System gesendet haben. So wie es ist, wartet das Kind immer noch darauf, dass die Daten ankommen, und wird nicht beendet, und das Elternteil wartet auf das Kind, das nicht zum Ausgang gehen wird, so dass Sie einen Deadlock haben.

Ich verwende die Fehler Reporting-Funktionen von stderr.c und stderr.h - der Code für die von GitHub verfügbar ist (https://github.com/jleffler/soq/tree/master/src/libsoq) Fehler zu melden (und Fortschritt).

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <sys/wait.h> 
#include "stderr.h" 

static int myPipe[2]; 

int main(int argc, char **argv) 
{ 
    pid_t pid; 
    int value; 
    int status; 
    err_setarg0(argv[0]); 
    err_setlogopts(ERR_PID|ERR_MICRO); 

    if (pipe(myPipe) != 0) 
     err_syserr("pipe failed: "); 

    // call fork() 
    printf("CS201 - Assignment 3 Premium - I. Forgot\n"); 
    pid = fork(); 
    if (pid < 0) 
     err_syserr("fork failed: "); 
    else if (pid == 0) 
    { 
     // -- running in child process -- 
     int sum = 0; 
     if (close(myPipe[1]) != 0) 
      err_syserr("failed to close write end of pipe in child: "); 

     for (int i = argc; i > 1; i--) 
     { 
      if (read(myPipe[0], &value, sizeof(value)) != sizeof(value)) 
       err_syserr("failed to read from parent: "); 
      sum += value; 
     } 
     if (close(myPipe[0]) != 0) 
      err_syserr("failed to close read end of pipe in child: "); 

     err_remark("Exiting: sum = %d\n", sum); 
     return sum; 
    } 
    else 
    { 
     // -- running in parent process -- 
     int sum = 0; 
     close(myPipe[0]); 

     for (int i = argc; i > 1; i--) 
     { 
      value = atoi(argv[i - 1]); 
      err_remark("Writing: %d\n", value); 
      if (write(myPipe[1], &value, sizeof(value)) != sizeof(value)) 
       err_syserr("failed to write to child: "); 
     } 
     if (waitpid(pid, &status, 0) != pid) 
      err_syserr("failed to wait for child %d: ", pid); 
     sum = status; 

     printf("sum = %d\n", sum); 
     if (WIFEXITED(status)) 
      printf("exit status: %d\n", WEXITSTATUS(status)); 
     return 0; 
    } 
} 

Und Beispielausgabe (Quellcode in fp71.c, Programm fp71):

$ gcc -O3 -g -I./inc -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes \ 
>  -Wstrict-prototypes fp71.c -o fp71 -L./lib -lsoq 
$ fp71 1 2 4 7 
CS201 - Assignment 3 Premium - I. Forgot 
fp71: 2017-08-15 20:11:48.453688 - pid=86097: Writing: 7 
fp71: 2017-08-15 20:11:48.454267 - pid=86097: Writing: 4 
fp71: 2017-08-15 20:11:48.454275 - pid=86097: Writing: 2 
fp71: 2017-08-15 20:11:48.454281 - pid=86097: Writing: 1 
fp71: 2017-08-15 20:11:48.454348 - pid=86098: Exiting: sum = 14 
sum = 3584 
exit status: 14 
$ 

Der Dezimalwert 3584 entspricht 0x0E00 auf hexadezimal. Wenn Sie das mit WIFEXITED() und WEXITSTATUS analzye, dann entspricht das 14, wie Sie erwarten würden. (Siehe auch Exit values bigger than 255 — possible?)

Verwandte Themen