PHP
Multiprocesamiento
Buscar..
Multiprocesamiento utilizando funciones de horquilla incorporadas.
Puede usar funciones incorporadas para ejecutar procesos PHP como forks. Esta es la forma más sencilla de lograr un trabajo paralelo si no necesita sus hilos para hablar entre sí.
Esto le permite realizar tareas que requieren mucho tiempo (como cargar un archivo a otro servidor o enviar un correo electrónico) a otro hilo para que su script se cargue más rápido y pueda usar múltiples núcleos, pero tenga en cuenta que esto no es un multihilo real y que su hilo principal no saber lo que los niños están haciendo.
Tenga en cuenta que en Windows esto hará que aparezca otro indicador de comando para cada bifurcación que inicie.
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);
Creando proceso hijo usando tenedor
PHP ha incorporado la función pcntl_fork
para crear procesos secundarios. pcntl_fork
es lo mismo que fork
en unix. No toma ningún parámetro y devuelve un entero que puede usarse para diferenciar entre el proceso principal y el secundario. Considere el siguiente código para explicación
<?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
}
?>
Como puede ver, -1
es un error en la bifurcación y no se creó el hijo. En la creación de child, tenemos dos procesos que se ejecutan con PID
separado.
Otra consideración aquí es un zombie process
o un zombie process
defunct process
cuando el proceso padre termina antes del proceso hijo. Para evitar un proceso de hijos zombis, simplemente agregue pcntl_wait($status)
al final del proceso padre.
pnctl_wait suspende la ejecución del proceso padre hasta que el proceso hijo haya salido.
También vale la pena señalar que el zombie process
no se puede SIGKILL
señal SIGKILL
.
Comunicación entre procesos
La comunicación entre procesos permite a los programadores comunicarse entre diferentes procesos. Por ejemplo, consideremos que necesitamos escribir una aplicación PHP que pueda ejecutar comandos de bash e imprimir la salida. Utilizaremos proc_open
, que ejecutará el comando y devolverá un recurso con el que podemos comunicarnos. El siguiente código muestra una implementación básica que ejecuta pwd
en bash
desde 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
ejecuta el comando bash
con $descriptor
como especificaciones del descriptor. Después de eso usamos is_resource
para validar el proceso. Una vez hecho esto, podemos comenzar a interactuar con el proceso hijo utilizando $ pipe, que se genera de acuerdo con las especificaciones del descriptor.
Después de eso, simplemente podemos usar fwrite
para escribir en el stdin del proceso hijo. En este caso pwd
seguido de retorno de carro. Finalmente, stream_get_contents
se usa para leer la stream_get_contents
del proceso hijo.
Siempre recuerde cerrar el proceso hijo utilizando proc_close () que terminará el hijo y devolverá el código de estado de salida.