Prozesse sollen kommunizieren
Jürgen Herz
- perl
Hallo Experten,
heute hatte ich mich mal an etwas schwierigeres gemacht - und scheitere nun prompt. Ich hoffe, daß jemand von euch mir helfen kann - und daß die Textmenge hier nicht abschreckend wirkt.
Ich habe zwei Perl-Scripte, die beide durchlaufen sollen, d.h. keines von beiden kann ständig beendet und wieder gestartet werden.
Script 1 wartet als Dämon auf bestimmte Ereignisse und soll die dann Script 2 melden, das einen Alert per Instant Messaging versenden soll.
Beides für sich läuft schön. Mein Problem ist nun, der Austausch der Meldung.
Ich hatte mich entschieden Script 2 am Anfang von Script 1 aus per
open INFORMANT, "| ./informat.pl";
zu starten. Dieses sollte meiner Vorstellung nach loopen und wenn es was auf STDIN gibt, den alert senden.
Grob gesagt sieht der Code so aus:
while(1) {
while (<STDIN>) {
sendalert($_);
}
listen_to_IM_server();
}
Tja, nur dummerweise blockt Perl an "while (<STDIN>)" solange Script 1 das Filehandle offen hat. Und von daher stehe ich nun dumm da.
Meine Fragen nun ist zweiteilig:
1. Gibt es irgendeine Möglichkeit, <STDIN> nichtblockend zu bekommen?
2. Gibt es insgesamt eine bessere Lösung für mein Problem als per anonymer Pipe?
Grüße,
Jürgen
Sup!
Ich hatte mich entschieden Script 2 am Anfang von Script 1 aus per
open INFORMANT, "| ./informat.pl";
zu starten. Dieses sollte meiner Vorstellung nach loopen und wenn es was auf STDIN gibt, den alert senden.
Grob gesagt sieht der Code so aus:
- Gibt es irgendeine Möglichkeit, <STDIN> nichtblockend zu bekommen?
Ja sicher. fcntl().
- Gibt es insgesamt eine bessere Lösung für mein Problem als per anonymer Pipe?
Öh... vielleicht? Aber wenn die Pipe reicht, wahrscheinlich nicht.
Gruesse,
Bio
- Gibt es irgendeine Möglichkeit, <STDIN> nichtblockend zu bekommen?
Ja sicher. fcntl().
Vielen Dank für Deine Antwort. In der Tat läßt sich das Handle mit
use Fcntl;
fcntl(STDIN, F_SETFL, O_NONBLOCK);
hinbiegen.
Danach hatte ich aber noch das Problem, daß der Empfänger (Skript 2), zwar nicht mehr gewartet hat, aber der Sender (Skript 1) schickte die Daten erst nach dem close INFORMANT auf die Reise.
Aber das ließ sich durch die Beantragung des Autoflushings nach dem Öffnen der Pipe lösen:
INFORMANT->autoflush(1);
Damit funktioniert es genauso wie erwartet.
Ciao,
Jürgen
Meine Fragen nun ist zweiteilig:
- Gibt es irgendeine Möglichkeit, <STDIN> nichtblockend zu bekommen?
- Gibt es insgesamt eine bessere Lösung für mein Problem als per anonymer Pipe?
Ich hab davon keine Ahnung, aber vielleicht solltest du mal in einer Perl Newsgroup nachfragen. Dort werden solche Sachen immer wieder sehr ausführlich diskutiert.
Struppi.