2017-01-31 3 views
2

Ich versuche, Rohre zu verstehen. Ich habe dieses kleine Programm, das eine Pipe verwendet, um eine Nachricht von dem übergeordneten Prozess zu seinem Kind zu senden. Das Kind erhält alle 3 Nachrichten, aber anstatt es zu beenden, bleibt es nach dem Lesen der letzten Nachricht hängen. Was mache ich falsch? Vielen Dank.Programm stoppt nicht nach dem Lesen von Rohr

PS: Ich habe festgestellt, dass es funktionieren würde, wenn ich für 2 Sekunden in der While-Schleife von den Eltern schlafen würde.

#include <stdlib.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <string.h> 
#include <errno.h> 

int main(){ 

    int desc[2]; 
    pipe(desc); 

    int pid = fork(); 

    if(pid == 0){ 
     while(1){ 
      sleep(1); 
      char buffer[16]; 
      if(read(desc[0], buffer, 16) != 16){ 
       printf("Error or finished"); 
       exit(0); 
      }; 
      printf("Child: message recieved - '%s'\n", buffer); 
     } 
     close(desc[1]); 
    } 
    if(pid > 0){ 
     int i=0; 
     while(i <= 2){ 
      char buffer[100]; 
      i++; char x[10]; 
      strcpy(buffer, "Hello, child!"); 
      sprintf(x, " %d", i); 
      strcat(buffer, x); 
      if(write(desc[1], buffer, 16) != 16){ 
       printf("Error"); 
       exit(0); 
      }; 
     } 
     close(desc[0]); 
    } 
    return 0; 
} 

Antwort

3

Sie haben vergessen, die nicht nützlichen Enden der Rohre in Eltern und Kind zu schließen. Tatsächlich besitzt Ihr Kind Lese- und Schreibteile der Pipe, so dass er das Ende der Datei nicht erkennen kann, da es einen Schreiber (selbst!) Gibt, so dass es beim Lesen blockiert ist. Ändern Sie Ihren Code:

if(pid == 0){ 
    close(desc[1]); // Child is not a writer, so close the write part immediately! 
    while(1){ 
     ... 
    } 
} 
if(pid > 0){ 
    close(desc[0]); // Parent is not a reader, so close the read part immediately! 
    int i=0; 
    while(i <= 2){ 
     ... 
    } 
} 

dass Denken Sie daran, an einem Rohr, End-of-Datei ist „nichts mehr zu lesen im Rohr“ und „nicht mehr Schriftsteller“.

3

Sie müssen die Rohrenden korrekt schließen. Der Reader bleibt hängen, bis alle Schreibenden der Pipe geschlossen sind.

if(pid == 0){ 
    close(desc[1]); // close write end in reader 
    while(1){ 
     ... 
     read(desc[0], buffer, 16); 
     ... 
    } 
} 
if(pid > 0){ 
    int i=0; 
    close(desc[0]); // close read end in writer; not required, but makes code cleaner 
    while(i <= 2){ 
     ... 
     write(desc[1], buffer, 16); 
     ... 
    } 
    close(desc[1]); // close write end in writer 
} 
+1

Sie haben recht mit "close write end in writer", aber nach diesem Punkt wird das übergeordnete Element beendet und somit wird der Dateideskriptor trotzdem geschlossen. Aber +1, um explizit zu sein. Der Austrittsmechanismus eines Kindes erscheint auch nicht natürlich. Aber das ist ein anderes Thema, denke ich. – usr

Verwandte Themen