Morris: Webserver wartet auf Scriptende

Hallo Leute!
Ich habe folgendes Problem:
Ein CGI-Skript (Perl) startet einen zeitaufwendigen Prozeß über exec. Nun warten Webserver (Apache 2.0) und Browser, bis der Prozeß beendet ist, bevor sie ihre Verbindung beenden. Ich hätte es lieber, wenn dem User mitgeteilt wird, daß es länger dauert, und die Verbindung beendet wird.

Meine Idee war, den Hauptprozeß über fork && exit(0) zu beenden, so daß der Kindprozeß dann das exec ausführt. Leider wird trotzdem auf das Ende gewartet. In dem Kommando ein "&" ans Ende zu setzen, hat auch nicht geholfen. Jetzt weiß ich nicht, was ich noch machen kann.

Vielen Dank für Eure Hilfe
Morris

  1. Sup!

    Wenn ich mich nicht irre, sind Parent und Child identisch, nur File-Locks und Signale des Eltern-Prozesses werden nicht an das Kind vererbt. File-Handles also anscheinend schon. Das könnte der Grund sein, dass der Web-Server wartet, denn er merkt wahrscheinlich gar nicht, dass der Eltern-Prozess Suizid begeht, wenn das Kind die File-Handles noch offen hält. Du musst also höchstwahrscheinlich noch irgendwas machen - z.B. das Kind die File-Handles schließen lassen.

    Gruesse,

    Bio

    --
    Never give up, never surrender!!!
    1. Hallo Bio!
      Danke für die schnelle Antwort.

      Wenn ich mich nicht irre, sind Parent und Child identisch, nur File-Locks und Signale des Eltern-Prozesses werden nicht an das Kind vererbt. File-Handles also anscheinend schon. Das könnte der Grund sein, dass der Web-Server wartet, denn er merkt wahrscheinlich gar nicht, dass der Eltern-Prozess Suizid begeht, wenn das Kind die File-Handles noch offen hält.

      Ich hatte gehofft, daß der Webserver (anhand der PID o.ä.) auf das Ende des Prozesses wartet, nicht aber auf das Ende von Kindprozessen. Aber das scheint nicht der Fall zu sein.

      Du musst also höchstwahrscheinlich noch irgendwas machen - z.B. das Kind die File-Handles schließen lassen.

      Das Problem ist, daß das Skript ja an STDOUT schreibt, und das wird an den Browser geschickt. Ich habe sogar schon ein
      close(STDOUT);
      versucht, aber das war eher eine Verzweiflungstat und hat auch nicht funktioniert. Auch ein
      open(TRASH, '>', '/dev/null');
      select(TRASH);
      bringt nichts, ebensowenig wie eine shell-Ausgabeumleitung an /dev/null innerhalb der exec-Anweisung.

      Woher sollen Webserver und Browser auch wissen, ob noch etwas an STDOUT kommt oder nicht? Irgendwie muß ich den Webserver dazu bringen, die Verbindung zu beenden, aber mir ist nicht klar, worauf er eigentlich wartet.

      Viele Grüße
      Morris

      1. Hallo,

        Das Problem ist, daß das Skript ja an STDOUT schreibt, und das wird an den Browser geschickt. Ich habe sogar schon ein
        close(STDOUT);
        versucht, aber das war eher eine Verzweiflungstat und hat auch nicht funktioniert. Auch ein
        open(TRASH, '>', '/dev/null');
        select(TRASH);
        bringt nichts, ebensowenig wie eine shell-Ausgabeumleitung an /dev/null innerhalb der exec-Anweisung.

        versuchs doch mal mit
          ~~~perl

        system(skript 2>/dev/null 1>/dev/null &);

          
        gruss
        
        -- 
        no strict;  
        no warnings;  
          
        Ich weiss es nicht, aber ich bin mir nicht sicher.  
        Craptastic.  
        Wenn ich groß bin, werde ich eine nervige künstliche Intelligenz.
        
        1. Hallo Eternius!
          Danke für die Antwort.

          versuchs doch mal mit
            ~~~perl

          system(skript 2>/dev/null 1>/dev/null &);

            
          Ok, auch STDERR umzuleiten habe ich noch nicht versucht. Ich probiers mal aus (wohl aber erst morgen).  
            
          Danke und Gruß  
          Morris
          
  2. Ich habe folgendes Problem:
    Ein CGI-Skript (Perl) startet einen zeitaufwendigen Prozeß über exec. Nun warten Webserver (Apache 2.0) und Browser, bis der Prozeß beendet ist, bevor sie ihre Verbindung beenden. Ich hätte es lieber, wenn dem User mitgeteilt wird, daß es länger dauert, und die Verbindung beendet wird.

    Ich bin nicht sicher, aber wenn ich exec richtig verstanden habe, wartet Perl nicht und kehrt auch nicht zurück:

    The exec function executes a system command and never returns
    ...

    und weiter:

    Since it's a common mistake to use exec instead of system, Perl warns you if there is a following statement which isn't die, warn, or exit (if -w is set - but you always do that). If you really want to follow an exec with some other statement, you can use one of these styles to avoid the warning:

    exec ('foo')   or print STDERR "couldn't exec foo: $!";
        { exec ('foo') }; print STDERR "couldn't exec foo: $!";

    Vielleicht hilft das weiter?

    Struppi.

    1. Hallo Struppi!

      Ich bin nicht sicher, aber wenn ich exec richtig verstanden habe, wartet Perl nicht und kehrt auch nicht zurück:

      Das stimmt, und das ist ja auch das Erwünschte. Das Problem ist, daß der Apache trotzdem auf das Ende des Kindprozesses wartet.

      Trotzdem danke für die Antwort.

      Gruß Morris

      1. Das stimmt, und das ist ja auch das Erwünschte. Das Problem ist, daß der Apache trotzdem auf das Ende des Kindprozesses wartet.

        Das hatte ich schon verstanden, ich fragte mich nur ob du:

        Since it's a common mistake to use exec instead of system, Perl warns you if there is a following statement which isn't die, warn, or exit (if -w is set - but you always do that). If you really want to follow an exec with some other statement, you can use one of these styles to avoid the warning:

        »

        exec ('foo')   or print STDERR "couldn't exec foo: $!";
            { exec ('foo') }; print STDERR "couldn't exec foo: $!";

        a. keine Warnung erhälst und
        b. or print STDERR "couldn't exec foo: $!"; ausprobiert hast.

        Da ich bisher noch nichts mit exec gemacht habe, ist das nur ein Schuss ins Blaue.
        Da wir aber ja weder etwas von den genauen Bedingungen Wissen, noch was du bereits versucht hast, ausser fork, wäre es interessant das auszuschliessen.

        Struppi.