joachim: Programme ausführen

Hi,

ich möchte mit PHP ein selbstgeschriebenes Programm starten das im Hintergrund laufen soll. Das Programm führt komplexe und langwierige Berechnungen und Dateioperationen durch die für PHP zu lange dauern würden bzw. so nicht möglich wären.

Bisher habe ich meine Programme immer mit @exec('Programm &');(ich verwende GNU/Linux) gestartet. Das '&' bewirkt ja ein starten im Hintergrund, aber läuft das Programm wirklich weiter wenn PHP seine Arbeit beendet?!

Ich habe feststellen müssen das dem leider nicht so ist.
PHP ist in rund 25 ms fertig und in dieser Zeit kommt mein C++ Programm   vermutlich grad mal dazu seine (36) Parameter zu parsen.

Ich hoffe ich habe mein Problem verständlich geschildert und es weis jemand eine Lösung.

Gruß Joachim

PS: Google hab ich schon zum Suchen gezwungen(bin auch immer noch dabei) wenn ich etwas finden sollte werde ich es sofort hier posten.

  1. Hallo Joachim,

    ich möchte mit PHP ein selbstgeschriebenes Programm starten das im Hintergrund laufen soll. Das Programm führt komplexe und langwierige Berechnungen und Dateioperationen durch die für PHP zu lange dauern würden bzw. so nicht möglich wären.

    Bisher habe ich meine Programme immer mit @exec('Programm &');(ich verwende GNU/Linux) gestartet. Das '&' bewirkt ja ein starten im Hintergrund, aber läuft das Programm wirklich weiter wenn PHP seine Arbeit beendet?!

    das hört sich vergleichbar zum Problem in diesem Archivthread an. Dort half folgender Archivbeitrag von Christian Seiler. Vielleicht kommst auch Du mit Christians Tipp weiter.

    Freundliche Grüße

    Vinzenz

    1. Vielen Dank für eure Antworten.

      Also so richtig geholfen haben mir eure Tipps bis jetzt noch nicht. Seit mir bitte nicht böse.

      Also ich erklär noch mal worums mir wirklich geht.

      • PHP startet ein Programm(im Hintergrund)
      • PHP beendet seine Arbeit
      • und das Programm läuft bis zu Ende weiter
      • PHP muss von dessen Ende nie etwas mitbekommen weil das Programm einen MySQL Eintrag macht.

      http://forum.de.selfhtml.org/archiv/2006/7/t133014/#m861318

      hier habe ich folgende Zeile gefunden:

      exec("$ProgExec > /dev/null &");

      Wenn ich aber dies bei mir einsetze:

      @exec('Programm [options] > /dev/null &');

      funktioniert es trotzdem nicht, was bewirkt diese Zeile?

      joachim

      1. Hello,

        http://forum.de.selfhtml.org/archiv/2006/7/t133014/#m861318

        hier habe ich folgende Zeile gefunden:

        exec("$ProgExec > /dev/null &");

        Wenn ich aber dies bei mir einsetze:

        @exec('Programm [options] > /dev/null &');

        funktioniert es trotzdem nicht, was bewirkt diese Zeile?

        Frag doch mal den Rückgabewert von exec() (1. Zeile reicht meistens) ab.

        Exec sollte hier ein Programm starten und als eigenständigen Prozess abspalten (&)
        Seine Ausgaben auf der Standardausgabe werden ins Nirwana geschickt.
        Es fehlt nun eigentlich noch die Bestimmung der PID. Die solltest Du nicht unter den Tisch kehren, sondern säuberlichst in eine Tabelle eintragen (mit Startzeitpunkt, usw.)

        Sollten sich dann Vagabunden-Prozesse ansammeln, kannst Du die wenigstens noch gezielt abwürgen.

        Dann fiel mir noch ein:
        In welchem Arbeitsverzeichnis wird Dein Programm durch Exec überhaupt aufgerufen? Vielleicht liegt da der Hase im Pfeffer?

        Harzliche Grüße vom Berg
        http://www.annerschbarrich.de

        Tom

        --
        Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
        Nur selber lernen macht schlau

        1. Exec sollte hier ein Programm starten und als eigenständigen Prozess abspalten (&)

          Ja aber wiso wird den der dann beim Ende vom PHP-Skript beendet? Weil es ein Child-Prozess von PHP ist?! Aber er wurde doch abgespalten?!

          Seine Ausgaben auf der Standardausgabe werden ins Nirwana geschickt.

          Das heisst soviel wie das das Programm keine Ausgabe macht?!
          Wie sähe es denn da mit Eingabeabfragen aus, wenn es welche gäbe?
          cin >>, scanf, getch, ...

          Es fehlt nun eigentlich noch die Bestimmung der PID. Die solltest Du nicht unter den Tisch kehren, sondern säuberlichst in eine Tabelle eintragen (mit Startzeitpunkt, usw.)

          Das verstehe ich leider nicht ganz. Könntest du diesen Schritt näher erklären? Welche Tabelle meinst du hier? Du Prozesstabelle von Linux???! Aber dort wird doch automatisch ein Eintrag erstellt?!

          Sollten sich dann Vagabunden-Prozesse ansammeln, kannst Du die wenigstens noch gezielt abwürgen.

          Wiso soll ich die gezielt abwürgen?
          Mein Programm beendet sich auf jeden Fall selbst.

          Dann fiel mir noch ein:
          In welchem Arbeitsverzeichnis wird Dein Programm durch Exec überhaupt aufgerufen? Vielleicht liegt da der Hase im Pfeffer?

          also das Programm selbst liegt im /etc/local/Programmname/ verzeichnis und im DocumentRoot des Apache/PHP, eben das Skriptverzeichnis, liegt ein Hardlink auf mein Programm.
          Wie kann den hier der Fehler liegen?

          joachim

          1. Hello,

            Es fehlt nun eigentlich noch die Bestimmung der PID. Die solltest Du nicht unter den Tisch kehren, sondern säuberlichst in eine Tabelle eintragen (mit Startzeitpunkt, usw.)

            Das verstehe ich leider nicht ganz. Könntest du diesen Schritt näher erklären? Welche Tabelle meinst du hier? Du Prozesstabelle von Linux???! Aber dort wird doch automatisch ein Eintrag erstellt?!

            Solange Du dir die PID nicht merkst, kannst Du nicht gezielt mit dem Prozess kommunizieren.

            Wiso soll ich die gezielt abwürgen?
            Mein Programm beendet sich auf jeden Fall selbst.

            Das ist bei keinem Programm wirklich sichergestellt.
            Eine falsch programmierte Schleife, und es läuft ewig.

            Dann fiel mir noch ein:
            In welchem Arbeitsverzeichnis wird Dein Programm durch Exec überhaupt aufgerufen? Vielleicht liegt da der Hase im Pfeffer?
            also das Programm selbst liegt im /etc/local/Programmname/ verzeichnis und im DocumentRoot des Apache/PHP, eben das Skriptverzeichnis, liegt ein Hardlink auf mein Programm.
            Wie kann den hier der Fehler liegen?

            Hast Du das Programm schon mal auf der Konsole aus einem anderen Verzeichnis als dem eigenen aufgerufen, und geschaut, was passiert? Wenn das Verzeichnis nun nicht für Dein Programm beschreibbar ist, was geschieht dann?

            Da hier diverse Unstetigkeiten vorliegen, sind die Freiheitsgrade zu groß, um Ferndiagnose vornehmen zu können.

            Versuch mal, das Programm so zu starten, wie es juha vorgeschlagen hat, übernimm die PID, lass Dein PHP-Programm hinterher in eine Schleife laufen (lass es immer 500ms schlafen) und den Zustand des Prozesses mit der PID ausgeben (ggf. in eine Datei).

            Sorge dafür, dass dieses Script abbricht, wenn der Browser die Seite verlässt (on User abort)

            Schau Dir die POSIX-Funktionen dazu an; die beiten eine Menge von Kontrollmöglichkeiten aus PHP heraus.

            Harzliche Grüße vom Berg
            http://www.annerschbarrich.de

            Tom

            --
            Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
            Nur selber lernen macht schlau

            1. Hello,

              Schau Dir die POSIX-Funktionen dazu an; die beiten eine Menge von Kontrollmöglichkeiten aus PHP heraus.

              Nun tut das Manual wieder

              http://www.php.net/manual/en/ref.posix.php

              posix_times()
              http://www.php.net/manual/en/function.posix-times.php
              könnte für Dich interessant sein, um im PHP-Script in jedem Schleifendurchlauf ausgegen zu werden. Damit kannst Du feststellen, ob der Prozess endet, auch wenn das PHP-Script noch läuft.

              Einen bequemen Weg gibt es hier nicht.
              Einmal must Du schon durch durch die Gestaltung einer mehrschichtigen Testapplikation, wenn Du den fehler finden willst. Die besteht dann eben aus mehreren Testprogrammen, die für sich alle getestet sind und dann nach und nach zusammengefügt werden.

              1. einfaches Programm unter dem OS, dass garantiert eine Weile läuft, dies
                 auch dokumentiert und z.B. erst abbricht, wenn eine Kontrolldatei (als Flag)
                 nicht mehr vorhanden ist.

              2. Startprozess unter PHP, der das einfache Programm startet, anschließend in einer
                 Schleife bis zum Schließen des Browserfensters weiterläuft, und den Zustans des
                 gestarteten Programmes feststellt und dokumentiert

              3. Kontroll-Request, um die Zustandsmeldungen des ersten Programmes abzufragen

              4. Kontroll-Request, um die Zustandsmeldungen des PHP-Programmes abzufragen.

              5. Löschprgramm für die Flag-Datei (falls das nicht über die Konsole möglich ist)

              Bitte, das ist kein Rezept, sondern nur ein Konzept, und kann noch Denkfehler haben.

              Harzliche Grüße vom Berg
              http://www.annerschbarrich.de

              Tom

              --
              Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
              Nur selber lernen macht schlau

          2. Hallo joachim.

            also das Programm selbst liegt im /etc/local/Programmname/ verzeichnis […]

            Kleine Anmerkung: Unter /usr/local wäre es besser aufgehoben. Das /etc-Verzeichnis ist eigentlich nur für Konfigurationsdateien gedacht.

            Einen schönen Freitag noch.

            Gruß, Mathias

            --
            ie:% fl:| br:< va:) ls:& fo:) rl:( n4:~ ss:) de:] js:| mo:| zu:)
            debian/rules
            1. Kleine Anmerkung: Unter /usr/local wäre es besser aufgehoben. Das /etc-Verzeichnis ist eigentlich nur für Konfigurationsdateien gedacht.

              »»
              Ja da ist es auch, keine Sorge. Hab mich wohl verschrieben. *rotwerd*

              Also das mit diesen POSIX funktionen ist nach meiner Ansicht nicht die richtige Lösung für mein Problem. Bitte nicht böse sein, ich hab sie mir schon angeschaut, aber ich denke nicht das ich so mein Problem aus der Welt schaffen kann.

              joachim

              1. Hello,

                Also das mit diesen POSIX funktionen ist nach meiner Ansicht nicht die richtige Lösung für mein Problem. Bitte nicht böse sein, ich hab sie mir schon angeschaut, aber ich denke nicht das ich so mein Problem aus der Welt schaffen kann.

                Zugegeben, für Deinen Fall passt da eigentlich nur wirklich die eine

                http://www.php.net/manual/en/function.posix-times.php

                Die gibt Dir Übersicht über den Prozess und lässt darauf schließen, ob er noch lebt.

                Hast Du denn mal die Testprogramme aufgebaut?

                Harzliche Grüße vom Berg
                http://www.annerschbarrich.de

                Tom

                --
                Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
                Nur selber lernen macht schlau

      2. echo $begrüßung;

        Wenn ich aber dies bei mir einsetze:
        @exec('Programm [options] > /dev/null &');
        funktioniert es trotzdem nicht, was bewirkt diese Zeile?

        Versuch bitte mal, Fehlermeldungen und Ausgabe umzuleiten:

        ... > /dev/null 2> /dev/null

        Vergleiche fastix' Ausführungen in </archiv/2005/9/t115661/>.

        echo "$verabschiedung $name";

  2. Hello,

    Bisher habe ich meine Programme immer mit @exec('Programm &');(ich verwende GNU/Linux) gestartet. Das '&' bewirkt ja ein starten im Hintergrund, aber läuft das Programm wirklich weiter wenn PHP seine Arbeit beendet?!

    im php-Manual unter http://www.php.net/manual/de/function.exec.php

    findest Du diverse Tipps von anderen benutzern.
    "juha" hat hier den für dich passenden gegeben.

    Du kannstr Dir also die PID des Prozesses besorgen und dann später mit einem weiteren Request und PHP danach schauen, ob sie noch lebt.

    siehe ausßerdem
    http://www.php.net/manual/de/function.connection-aborted.php

    http://www.php.net/manual/de/features.connection-handling.php

    Harzliche Grüße vom Berg
    http://www.annerschbarrich.de

    Tom

    --
    Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
    Nur selber lernen macht schlau

    1. Hello,

      ich wollte Dir zusätzlich noch die POSIX-Funktionen nahelegen.
      Damit kannst Du auf Rechteverwaltung, Prozesse, etc. zugreifen.
      Aber leider streikt das PHP-Manual an der Stelle.
      Solltest Du also später selbst nochmal gucken.

      Harzliche Grüße vom Berg
      http://www.annerschbarrich.de

      Tom

      --
      Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
      Nur selber lernen macht schlau