Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Lesen von einer Pipe stoppen

23 views
Skip to first unread message

Martin Horster

unread,
May 12, 2003, 5:34:49 PM5/12/03
to
Hallo,
also ich hab hier eine einfache Pipe:
int p[2];
pipe(p);
Nun lese ich von einer Datei, schreibe den Inhalt, z.B. ein Zeichen in die
Pipe, lese es dann am Ende der Pipe wieder aus und verarbeite das... Das
Lesen läuft solange bis es am Ende der Datei angelangt ist. Nur: wie mach
ich das dem read() am Ende der Pipe klar, das da nichts mehr kommt und aus
der Endlosschleife rausgeht?

Danke,
Martin

Kai Ruhnau

unread,
May 12, 2003, 6:17:15 PM5/12/03
to
> Nun lese ich von einer Datei, schreibe den Inhalt, z.B. ein Zeichen in die
> Pipe, lese es dann am Ende der Pipe wieder aus und verarbeite das... Das
> Lesen läuft solange bis es am Ende der Datei angelangt ist. Nur: wie mach
> ich das dem read() am Ende der Pipe klar, das da nichts mehr kommt und aus
> der Endlosschleife rausgeht?

Da ich das vorgestern gelernt habe, zitiere ich jetzt mal ganz dreist ;D

"Bodo Thiesen" <bot...@gmx.de> schrieb im Newsbeitrag
news:b9k2o8$un7$1...@bodo-thiesen-server.dyndns.org...
> Das Problem ist folgendes: read blockiert solange das "Schreib-Ende" der
> Pipe offen ist, da noch Daten ankommen könnten. Lösung: Das Schreib-Ende
> schließen, sobalt der Text geschrieben wurde. Der Thread muß fd 1
> schließen, und die mutter muß fd 1 schließen, sobald der Text geschrieben
> wurde.

Grüße
Kai


Helmut Schellong

unread,
May 12, 2003, 6:46:03 PM5/12/03
to
Martin Horster wrote:
> Hallo,
> also ich hab hier eine einfache Pipe:
> int p[2];
> pipe(p);
> Nun lese ich von einer Datei, schreibe den Inhalt, z.B. ein Zeichen in die
> Pipe, lese es dann am Ende der Pipe wieder aus und verarbeite das... Das
> Lesen läuft solange bis es am Ende der Datei angelangt ist. Nur: wie mach

> ich das dem read() am Ende der Pipe klar, das da nichts mehr kommt und aus
> der Endlosschleife rausgeht?

Der in die Pipe schreibende Prozeß muß seinen Pipe-Schreib-Handle
schließen, sobald er alles geschrieben hat, was zu schreiben war.

Der Leser erhält dann einfach 0==read(ph[0], ...........
Dann kann der Leser close(ph[0]) machen, und der
Transfer ist beendet.

--
Mit freundlichen Grüßen
Helmut Schellong po...@schellong.de po...@schellong.com
www.schellong.de www.schellong.biz sche...@t-online.de
http://www.wikiservice.at/dse/wiki.cgi?FreeBSD

Martin Horster

unread,
May 13, 2003, 2:28:19 AM5/13/03
to
Helmut Schellong wrote:
> Der in die Pipe schreibende Prozeß muß seinen Pipe-Schreib-Handle
> schließen, sobald er alles geschrieben hat, was zu schreiben war.
Also nachdem write(ph[1],....) sozusagen nichts mehr schreibt, kommt ein
close(ph[1]), und dann sollte der reader 0 bekommen, und das ist die
Abbruchbedingung. Das mach ich, nur das read(ph[0],...), bleibt stehen und
wartet anscheinend noch immer.
Ist doch korrekt, wenn ich das mit einer
while(read(ph[0], buf, sizeof(buf))>0){...}
mache, oder?

Danke,
Martin

Helmut Schellong

unread,
May 13, 2003, 3:05:39 AM5/13/03
to
Martin Horster wrote:
> Helmut Schellong wrote:
>
>>Der in die Pipe schreibende Prozeß muß seinen Pipe-Schreib-Handle
>>schließen, sobald er alles geschrieben hat, was zu schreiben war.

>
> Also nachdem write(ph[1],....) sozusagen nichts mehr schreibt, kommt ein
> close(ph[1]), und dann sollte der reader 0 bekommen, und das ist die
> Abbruchbedingung. Das mach ich, nur das read(ph[0],...), bleibt stehen und
> wartet anscheinend noch immer.

Das kann nicht sein.
Ich hab das selbst schon oft programmiert.

> Ist doch korrekt, wenn ich das mit einer
> while(read(ph[0], buf, sizeof(buf))>0){...}
> mache, oder?

Ja.

Schließt Du auch den Lesehandle des Pipe-Schreibers
und den Schreibhandle des Pipe-Lesers jeweils sofort?
(Dürfte allerdings nichts machen, wenn nicht.)

Martin Horster

unread,
May 13, 2003, 3:59:02 AM5/13/03
to
Helmut Schellong wrote:
>> Also nachdem write(ph[1],....) sozusagen nichts mehr schreibt, kommt ein
>> close(ph[1]), und dann sollte der reader 0 bekommen, und das ist die
>> Abbruchbedingung. Das mach ich, nur das read(ph[0],...), bleibt stehen
>> und wartet anscheinend noch immer.
>> Das kann nicht sein.
> Ich hab das selbst schon oft programmiert.
Nun gut, ich hab das mal nun in einem einfachen Programm mal ausgetestet und
es funktioniert, wie du schon sagtest. Nur ich mach das analog im
eigentlichen Programm, funktioniert aber nicht. Gibt es da vielleicht sonst
noch Dinge, die zu beachten sind. Könnte es vielleicht daran liegen, dass
mehrer Pipes vorhanden sind oder sonst was? Oder an den Prozessen Kind,
Elternteil?

> Schließt Du auch den Lesehandle des Pipe-Schreibers
> und den Schreibhandle des Pipe-Lesers jeweils sofort?
> (Dürfte allerdings nichts machen, wenn nicht.)
Ja.

Aja, noch was zu meinem Testprogramm: nachdem write(ph[1]...) beendet ist,
schließe ich es mit close(ph[1]). Das alleine hat bei mir aber nicht
gereicht, ich _muss_ auch direkt vor der while(read(ph[0]...)) ein
close(ph[1]), damit es in dem Beispiel funktioniert.

Ciao,
Martin

Helmut Schellong

unread,
May 13, 2003, 9:01:48 AM5/13/03
to
Martin Horster wrote:
> Helmut Schellong wrote:
>
>>>Also nachdem write(ph[1],....) sozusagen nichts mehr schreibt, kommt ein
>>>close(ph[1]), und dann sollte der reader 0 bekommen, und das ist die
>>>Abbruchbedingung. Das mach ich, nur das read(ph[0],...), bleibt stehen
>>>und wartet anscheinend noch immer.
>>>Das kann nicht sein.
>>
>>Ich hab das selbst schon oft programmiert.
>
> Nun gut, ich hab das mal nun in einem einfachen Programm mal ausgetestet und
> es funktioniert, wie du schon sagtest. Nur ich mach das analog im
> eigentlichen Programm, funktioniert aber nicht. Gibt es da vielleicht sonst
> noch Dinge, die zu beachten sind. Könnte es vielleicht daran liegen, dass

> mehrer Pipes vorhanden sind oder sonst was? Oder an den Prozessen Kind,
> Elternteil?
>
>>Schließt Du auch den Lesehandle des Pipe-Schreibers

>>und den Schreibhandle des Pipe-Lesers jeweils sofort?
>>(Dürfte allerdings nichts machen, wenn nicht.)

>
> Ja.
>
> Aja, noch was zu meinem Testprogramm: nachdem write(ph[1]...) beendet ist,
> schließe ich es mit close(ph[1]). Das alleine hat bei mir aber nicht

> gereicht, ich _muss_ auch direkt vor der while(read(ph[0]...)) ein
> close(ph[1]), damit es in dem Beispiel funktioniert.

Du hast doch oben "Ja." geschrieben!
Und hier unten sagst Du close(ph[1] vor while(read

Das meine ich doch damit!

Der Vater macht sofort nach pipe() close(ph[0]),
der Child (Leser) sofort zu Anfang (im fork-{}) close(ph[1].

Martin Horster

unread,
May 13, 2003, 2:35:33 PM5/13/03
to
Helmut Schellong wrote:
> Der Vater macht sofort nach pipe() close(ph[0]),
> der Child (Leser) sofort zu Anfang (im fork-{}) close(ph[1].
Mir war nicht bewusst, dass das wirklich unmittelbar danach zu passieren
hat. Dachte, es reiche, wenn ich es vor dem read() oder write() mache. Also
vielen Dank!

Ciao,
Martin

Helmut Schellong

unread,
May 13, 2003, 4:00:02 PM5/13/03
to

Etwas falsch verstanden haste das schon.

Eine pipe() hat doch *zwei* Kanäle.
Wenn man nur einen braucht, schließen eben beide
Parteien ihr Ende des unbenutzten Kanals.
Und das sofort - warum nicht sofort?;
spätestens, bevor die Pipe konkret durch write/read
benutzt wird (Beide Parteien gleichzeitig betrachtet).

Funktioniert das denn bei Dir jetzt uneingeschränkt?

Martin Horster

unread,
May 13, 2003, 4:52:13 PM5/13/03
to
Helmut Schellong wrote:
> Funktioniert das denn bei Dir jetzt uneingeschränkt?
Also ehrlich gesagt, wenn ich das close(p[1]...) unmittelbar vor dem
(while(read(p[0]...)>0) mache, funktioniert das nicht. D.h. ich muss direkt
nach einem fork() oder pipe() das 'andere' Ende schließen.

Ciao,
Martin

Bodo Thiesen

unread,
May 13, 2003, 4:27:07 PM5/13/03
to
Martin Horster schrieb:

Es reicht auch, wenn man es irgendwann macht, nur wenn man es nicht sofort
macht vergisst man es hinterher (zumindest laut Murphy's Gesetz).
--
Gruß, Bodo [DE: http://piology.org/ILOVEYOU-Signature-FAQ.html]

@@@@@ GEGEN TCG aka. TCPA: @@@@@ [DE: http://www.againsttcpa.com]
Wer fragt ist nur drei Minuten Dumm.

Bodo Thiesen

unread,
May 13, 2003, 4:27:12 PM5/13/03
to
Helmut Schellong schrieb:

> Schließt Du auch den Lesehandle des Pipe-Schreibers
> und den Schreibhandle des Pipe-Lesers jeweils sofort?
> (Dürfte allerdings nichts machen, wenn nicht.)

Lese-Handle beim Schreibprozess ist egal. Aber das Schreib-Handle muß
*zwingend* beim Lese-Prozess geschlossen werden.

Bodo Thiesen

unread,
May 13, 2003, 11:13:33 PM5/13/03
to
Martin Horster schrieb:

> Helmut Schellong wrote:
>> Funktioniert das denn bei Dir jetzt uneingeschränkt?
> Also ehrlich gesagt, wenn ich das close(p[1]...) unmittelbar vor dem
> (while(read(p[0]...)>0) mache, funktioniert das nicht.

Poste nochmal den Quelltext - irgendwie kommt mir das Komisch vor.

A D.h. ich muss
> direkt nach einem fork()

Hatte Helmut inzwischen schon zweimal vorgeschlagen. Ja.

> oder pipe()

Nein, wenn dann nützt Dir das andere Ende auch nichts mehr. Mindestens ein
dup (oder dup2) oder fork (oder clone) muß schon zwischen pipe und close
sein.

> das 'andere' Ende schließen.

Martin Horster

unread,
May 14, 2003, 2:53:31 AM5/14/03
to
Bodo Thiesen wrote:
> Martin Horster schrieb:
>
>> Helmut Schellong wrote:
>>> Funktioniert das denn bei Dir jetzt uneingeschränkt?
>> Also ehrlich gesagt, wenn ich das close(p[1]...) unmittelbar vor dem
>> (while(read(p[0]...)>0) mache, funktioniert das nicht.
>
> Poste nochmal den Quelltext - irgendwie kommt mir das Komisch vor.
>
> A D.h. ich muss
>> direkt nach einem fork()
>
> Hatte Helmut inzwischen schon zweimal vorgeschlagen. Ja.
>
>> oder pipe()
>
> Nein, wenn dann nützt Dir das andere Ende auch nichts mehr. Mindestens ein
> dup (oder dup2) oder fork (oder clone) muß schon zwischen pipe und close
> sein.
Ok, hab den ganzen Code mal neu geschrieben, und jetzt funktioniert auch
alles wie es sollte. Kann aber nicht wirklich sagen, warum das vorher mit
dem close() vor der while(read()) nicht geklappt hat, war wahrscheinlich
schon zu unübersichtlich. Jetzt hab ich die close()s direkt nach dem
fork(), und dass ein close() nach dem pipe() keine gute Idee ist, ist mir
dann auch aufgefallen.
Also nochmals Danke!

Ciao,
Martin

Felix von Leitner

unread,
May 14, 2003, 5:49:15 AM5/14/03
to
Thus spake Helmut Schellong (sche...@t-online.de):

> Und hier unten sagst Du close(ph[1] vor while(read

Oh Mann, unser kleines haariges Sumpftröllchen pinkelt ja immer noch die
Newbies mit falschen Ratschlägen an. Diese Newsgroup ist echt verloren.

> Das meine ich doch damit!

Klar, aber sicher doch. Natürlich! Wie konnte das je jemand bezweifeln!

> Der Vater macht sofort nach pipe() close(ph[0]),

Bullshit. Nach fork, nicht nach pipe.
Eine Pipe, bei der sofort das eine Ende geschlossen wird, ist sinnlos.
Aber wem erzähle ich das. Man sieht ja, was bsh-Benutzung mit dem Hirn
anstellt (ich postuliere mal, das vorher eines da war).

> der Child (Leser) sofort zu Anfang (im fork-{}) close(ph[1].

Solange du nicht mal die rudimentäre Syntax von C-Funktionsaufrufen
hinkriegst, ist deine Anwesenheit hier nicht erwünscht.

0 new messages