Frage

unten Dieser Code ist für ls -l Ausführung | wc -l. Im Code, wenn ich in der Nähe Kommentar (p [1]) in Mutter dann hängt das Programm nur für eine Eingabe wartet. Warum ist es so? Das Kind schreibt Ausgabe von ls auf p1 und Eltern sollte die Ausgabe von p0 genommen hat.

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

main ()
{
  int i;
  int p[2];
  pid_t ret;
  pipe (p);
  ret = fork ();

  if (ret == 0)
    {
      close (1);
      dup (p[1]);
      close (p[0]);
      execlp ("ls", "ls", "-l", (char *) 0);
    }

  if (ret > 0)
    {
      close (0);
      dup (p[0]);
      //Doubt, Commenting the line below does not work WHy?
      close (p[1]);
      wait (NULL);
      execlp ("wc", "wc", "-l", (char *) 0);
    }
}
War es hilfreich?

Lösung

pipe + fork schafft 4 Filedeskriptoren, sind zwei Eingänge

Bevor die Gabel Sie haben ein einzelnes Rohr mit einem Eingang und einem Ausgang.

Nach der Gabel Du ein einzelnes Rohr mit zwei Eingängen und zwei Ausgängen hat.

Wenn Sie zwei Eingänge für das Rohr haben (dh ein proc schreibt) und zwei Ausgänge (dh ein proc von liest), müssen Sie den anderen Eingang oder der Leser schließen wird auch eine Pipeeingabe hat, die geschlossen werden nie.

In Ihrem Fall ist die Mutter die Leser, und zusätzlich zu dem Ausgangsende des Rohres, hat es ein offenes anderes Ende oder Eingangsende des Rohres, das Zeug könnte, in der Theorie werden, geschrieben. Als Ergebnis sendet das Rohr nie ein EOF, weil, wenn das Kind das Rohr verlässt noch offen ist aufgrund der nicht verwendeten fd der Eltern.

So die Eltern Deadlocks, wartet immer für sie selbst zu schreiben.

Andere Tipps

Beachten Sie, dass ‚dup(p[1])‘ bedeutet, dass Sie zwei Dateideskriptoren haben auf die gleiche Datei verweisen. Es lässt sich nicht schließen p[1]; Sie sollten das ausdrücklich tun. Ebenfalls mit ‚dup(p[0])‘. Man beachte, dass ein Dateideskriptor aus einem Rohr Lesen nur Null-Bytes zurückgibt (EOF), wenn es keine Schreib offenen Datei-Deskriptoren für das Rohr; bis der letzte Schreib Descriptor geschlossen ist, wird der Leseprozess auf unbestimmte Zeit hängen. Wenn Sie das Schreibende dup() gibt es zwei offene Dateideskriptoren mit dem Schreibende, und beide müssen geschlossen werden, bevor der Lesevorgang EOF wird.

Sie auch brauchen oder wollen nicht den wait() Anruf in Ihrem Code. Wenn die ls Auflistung ist größer als ein Rohr halten kann, wird Ihre Prozesse Deadlock, mit dem Kind warten ls zu vervollständigen und ls warten, bis das Kind mit dem Lesen der Daten zu erhalten, auf der es geschrieben hat.

Wenn das redundante Material abgestreift wird, wird der Arbeits Code wird:

#include <unistd.h>

int main(void)
{
    int p[2];
    pid_t ret;
    pipe(p);
    ret = fork();

    if (ret == 0)
    {
        close(1);
        dup(p[1]);
        close(p[0]);
        close(p[1]);
        execlp("ls", "ls", "-l", (char *) 0);
    } 
    else if (ret > 0)
    {
        close(0);
        dup(p[0]);
        close(p[0]);
        close(p[1]);
        execlp("wc", "wc", "-l", (char *) 0);
    }
    return(-1);
}

Unter Solaris 10 wird diese kompiliert ohne Warnung mit:

Black JL: gcc -Wall -Werror -Wmissing-prototypes -Wstrict-prototypes -o x x.c
Black JL: ./x
      77
Black JL:

Wenn das Kind nicht in der Nähe p[1] tut, dann ist das FD in zwei Verfahren offen ist - Eltern und Kind. Die Mutter schließt es schließlich, aber das Kind nie tut - so die FD bleibt offen. Deshalb jeder Leser dieser FD (das Kind in diesem Fall) wird ewig warten nur für den Fall mehr schreibt es wird auf sie getan wird ... es ist nicht, aber der Leser einfach nicht wissen! -)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top