Frage

Ich hatte bei der Ausführung unter Windows einige Probleme mit dem Forken von Prozessen aus einem Perl-CGI-Skript.Das Hauptproblem scheint zu sein, dass „Fork“ bei der Ausführung unter Windows emuliert wird und scheinbar keinen neuen Prozess erstellt (nur einen weiteren Thread im aktuellen).Das bedeutet, dass Webserver (wie IIS), die auf den Abschluss des Prozesses warten, weiterhin warten, bis der „Hintergrund“-Prozess abgeschlossen ist.

Gibt es eine Möglichkeit, unter Windows einen Hintergrundprozess von einem CGI-Skript abzuspalten?Noch besser: Gibt es eine einzige Funktion, die ich aufrufen kann, um dies plattformübergreifend zu tun?

(Und um das Leben noch schwieriger zu machen, hätte ich gerne eine gute Möglichkeit, die Ausgabe der gespaltenen Prozesse gleichzeitig in eine Datei umzuleiten.)

War es hilfreich?

Lösung

Wenn Sie dies plattformunabhängig tun möchten, Proc::Hintergrund ist wahrscheinlich der beste Weg.

Andere Tipps

Verwenden Win32::Prozess->Erstellen mit dem Parameter DETACHED_PROCESS

Perlgabel:

Perl bietet ein Fork () -Stegeswort, das dem gleichnamigen Unix -Systemanruf entspricht.Auf den meisten Unix-ähnlichen Plattformen, auf denen der Fork () -Systemaufruf verfügbar ist, nennt Perl Fork () ihn einfach.

Auf einigen Plattformen wie Windows, auf denen der Fork () -Systemaufruf nicht verfügbar ist, kann Perl so erstellt werden, dass Fork () auf der Interpret -Ebene emuliert wird.Während die Emulation mit der Real Fork () auf der Ebene des Perl -Programms so kompatibel wie möglich ist, gibt es bestimmte wichtige Unterschiede, die darauf zurückzuführen sind im gleichen realen Prozess in Bezug auf das Betriebssystem.

Ich habe echte Probleme mit fork() unter Windows festgestellt, insbesondere beim Umgang mit Win32-Objekten in Perl.Wenn es also Windows-spezifisch sein soll, würde ich Ihnen wirklich empfehlen, einen Blick auf die Thread-Bibliothek in Perl zu werfen.

Ich nutze dies mit gutem Erfolg, indem ich auf Websites, die IIS verwenden, mehr als eine Verbindung gleichzeitig akzeptiere und dann noch mehr Threads verwende, um verschiedene Skripte gleichzeitig auszuführen.

Diese Frage ist sehr alt und die akzeptierte Antwort ist richtig.Allerdings habe ich das gerade erst zum Laufen gebracht und dachte, ich würde noch ein paar Details dazu hinzufügen, wie man es für jeden, der es braucht, umsetzen kann.

Der folgende Code existiert in einem sehr großen Perl-CGI-Skript.Diese spezielle Unterroutine erstellt Tickets in mehreren Ticketsystemen und verwendet dann die zurückgegebenen Ticketnummern, um einen automatisierten Anruf über Twilio-Dienste zu tätigen.Der Anruf dauert eine Weile und ich wollte nicht, dass die CGI-Benutzer warten müssen, bis der Anruf beendet ist, um die Ausgabe ihrer Anfrage zu sehen.Zu diesem Zweck habe ich Folgendes getan:

  (All the CGI code that is standard stuff.  Calls the subroutine needed, and then)

  my $randnum = int(rand(100000));
  my $callcmd = $progdir_path . "/aoff-caller.pl --uniqueid $uuid --region $region --ticketid $ticketid";
  my $daemon = Proc::Daemon->new(
    work_dir     => $progdir_path,
    child_STDOUT => $tmpdir_path . '/stdout.txt',
    child_STDERR => $tmpdir_path . '/stderr.txt',
    pid_file     => $tmpdir_path . '/' . $randnum . '-pid.txt',
    exec_command => $callcmd,
  );
  my $pid = $daemon->Init();

  exit 0;

  (kill CGI at the appropriate place)

Ich bin mir sicher, dass die generierte und an die PID angehängte Zufallszahl übertrieben ist, aber ich habe kein Interesse daran, Probleme zu schaffen, die sich extrem leicht vermeiden lassen.Hoffentlich hilft das jemandem, der das Gleiche tun möchte.Denken Sie daran, hinzuzufügen use Proc::Daemon Spiegeln Sie am Anfang Ihres Skripts den Code und ändern Sie die Pfade und Namen Ihres Programms, und schon kann es losgehen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top