PHP
Multiprocessing
Suche…
Multiprocessing mit integrierten Gabelfunktionen
Sie können integrierte Funktionen verwenden, um PHP-Prozesse als Gabeln auszuführen. Dies ist der einfachste Weg, um parallele Arbeit zu erzielen, wenn Sie nicht benötigen, dass Ihre Threads miteinander sprechen.
Auf diese Weise können Sie zeitintensive Aufgaben (z. B. das Hochladen einer Datei auf einen anderen Server oder das Senden einer E-Mail) in einen anderen Thread übernehmen, sodass das Skript schneller geladen wird und mehrere Kerne verwendet werden können. Beachten Sie jedoch, dass dies kein echtes Multithreading ist und Ihr Haupt-Thread nicht wissen, was die Kinder vorhaben.
Beachten Sie, dass unter Windows eine neue Eingabeaufforderung für jede Gabelung erscheint, die Sie starten.
master.php
$cmd = "php worker.php 10";
if(strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') // for windows use popen and pclose
{
pclose(popen($cmd,"r"));
}
else //for unix systems use shell exec with "&" in the end
{
exec('bash -c "exec nohup setsid '.$cmd.' > /dev/null 2>&1 &"');
}
worker.php
//send emails, upload files, analyze logs, etc
$sleeptime = $argv[1];
sleep($sleeptime);
Unterprozess mit Fork erstellen
PHP hat die Funktion pcntl_fork
zum Erstellen eines pcntl_fork
Prozesses eingebaut. pcntl_fork
ist identisch mit fork
in Unix. Es nimmt keine Parameter auf und gibt eine Ganzzahl zurück, die zur Unterscheidung zwischen dem übergeordneten und dem untergeordneten Prozess verwendet werden kann. Betrachten Sie den folgenden Code zur Erläuterung
<?php
// $pid is the PID of child
$pid = pcntl_fork();
if ($pid == -1) {
die('Error while creating child process');
} else if ($pid) {
// Parent process
} else {
// Child process
}
?>
Wie Sie sehen, ist -1
ein Fehler in Fork und das Kind wurde nicht erstellt. Bei der Erstellung eines Kindes haben wir zwei Prozesse, die mit einer separaten PID
.
Eine weitere Überlegung ist hier ein zombie process
oder ein nicht mehr vorhandener defunct process
wenn der übergeordnete Prozess vor dem untergeordneten Prozess abgeschlossen ist. Um einen Zombie-Kinderprozess zu verhindern, fügen pcntl_wait($status)
einfach am Ende des Elternprozesses pcntl_wait($status)
.
pnctl_wait setzt die Ausführung des übergeordneten Prozesses aus, bis der untergeordnete Prozess beendet wurde.
Es ist auch erwähnenswert, dass der zombie process
nicht mit dem SIGKILL
Signal beendet werden kann.
Interprozesskommunikation
Interprozesskommunikation ermöglicht Programmierern die Kommunikation zwischen verschiedenen Prozessen. Nehmen wir zum Beispiel an, wir müssen eine PHP-Anwendung schreiben, die Bash-Befehle ausführen und die Ausgabe drucken kann. Wir verwenden proc_open
, das den Befehl ausführt und eine Ressource proc_open
, mit der wir kommunizieren können. Der folgende Code zeigt eine grundlegende Implementierung, die pwd
in bash
von php
aus php
<?php
$descriptor = array(
0 => array("pipe", "r"), // pipe for stdin of child
1 => array("pipe", "w"), // pipe for stdout of child
);
$process = proc_open("bash", $descriptor, $pipes);
if (is_resource($process)) {
fwrite($pipes[0], "pwd" . "\n");
fclose($pipes[0]);
echo stream_get_contents($pipes[1]);
fclose($pipes[1]);
$return_value = proc_close($process);
}
?>
proc_open
führt den bash
Befehl mit $descriptor
als Deskriptor-Spezifikation aus. Danach verwenden wir is_resource
, um den Prozess zu is_resource
. Sobald dies erledigt ist, können wir mit dem untergeordneten Prozess mit $ Pipes interagieren, die gemäß den Deskriptor-Spezifikationen generiert werden.
Danach können wir einfach mit fwrite
in den fwrite
des Kindprozesses schreiben. In diesem Fall folgt pwd
gefolgt von einem Wagenrücklauf. Schließlich wird stream_get_contents
verwendet, um stdout des stream_get_contents
Prozesses zu lesen.
Denken Sie immer daran, den untergeordneten Prozess mithilfe von proc_close () zu schließen, wodurch das untergeordnete Element beendet und der Beendigungsstatuscode zurückgegeben wird.