/ / bezüglich der Beziehung von close () und read () - c, process, pipe

in Bezug auf die Beziehung von close () und read () - c, Prozess, Rohr

int main()
{
char *msg="hello";
char buff[MAX];
int p[2];
pipe(p);
int i,pid=fork();
if(pid>0){
//close(p[1]);
read(p[0],buff, MAX);
}
else
{
printf("child exitingn");
}
}

Warum blockiert der obige Code? Aber dann, wenn wir den Kommentar entfernen und platzieren

close(p[1])

Warum endet der Code dann sofort?

Antworten:

2 für die Antwort № 1

Sobald Sie eine Pipe erstellt haben, erhält sie vier Enden:

  • Ein Leseende p[0] im übergeordneten Prozess
  • Ein Schreibende p[1] im übergeordneten Prozess
  • Ein Leseende p[0] im Kindprozess
  • Ein Schreibende p[1] im Kindprozess

UNIX liefert nicht EOF an den Leser, es sei denn, beide Schreibenden wurden geschlossen, weil es weiß, dass die Pipe noch beschreibbar ist.

Wenn der Kindprozess beendet wird, schließt er beide Enden des Rohrs auf seiner Seite. Das übergeordnete Element verfügt jedoch immer noch über ein schreibbares Ende, also lesen Sie von den Rohrblöcken, anstatt ein EOF zum Elternteil. Aus diesem Grund weist das UNIX-Handbuch an, die unbenutzten Enden der Pipe sofort zu schließen:

Eine Anwendung, die verwendet pipe(2) und fork(2) sollte geeignet verwenden close(2) ruft auf, um unnötige doppelte Dateideskriptoren zu schließen; Dies stellt sicher, dass das Ende der Datei und SIGPIPE/EPIPE werden bei Bedarf geliefert.

Hier ist ein Beispiel, wie Sie Ihr Programm nicht blockieren lassen, ohne es zu schließen p[1] auf der Elternseite:

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

void* write_pipe(void* pp) {
int* p = (int*)pp;
char msg[] = "Hello from another thread!";
write(p[1], msg, sizeof(msg));
return NULL;
}

int main()
{
char buff[100];
int p[2];
pipe(p);
int pid=fork();
if(pid>0){
pthread_t thread1;
pthread_create (&thread1, NULL, &write_pipe, (void *)p);
read(p[0],buff, 100);
printf("%sn", buff);
printf("parent exitingn");
}
else
{
printf("child exitingn");
}
return 0;
}

Der obige Code schreibt auf das Schreibende despipe aus einem Thread innerhalb des übergeordneten Prozesses, anstatt aus dem untergeordneten Prozess darauf zu schreiben. Dies ist auch eine legitime Verwendung einer Pipe, die veranschaulicht, warum UNIX nicht liefern kann EOF es sei denn, das Schreibende des Rohres ist geschlossen.


0 für die Antwort № 2

Lesen ist ein blockierender Aufruf und es gibt nur zurück, wenn es EOF empfängt. Wenn Sie das Schreibende der Pipe nicht schließen, wird das Ende nicht gelesen und das Programm bleibt blockiert