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 № 1Sobald 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)
undfork(2)
sollte geeignet verwendenclose(2)
ruft auf, um unnötige doppelte Dateideskriptoren zu schließen; Dies stellt sicher, dass das Ende der Datei undSIGPIPE
/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