Jürgen Herz: Prozesse sollen kommunizieren

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

  1. 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:

    1. Gibt es irgendeine Möglichkeit, <STDIN> nichtblockend zu bekommen?

    Ja sicher. fcntl().

    1. 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

    --
    Keep your friends close, but your enemies closer!
      1. 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

  2. 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?

    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.