tomar - ¿Cómo se puede usar subprocesos múltiples en aplicaciones PHP?
seleccionar combobox php (18)
¿Existe una forma realista de implementar un modelo de subprocesos múltiples en PHP, ya sea de verdad, o simplemente simularlo? Hace algún tiempo se sugirió que podría forzar al sistema operativo a cargar otra instancia del ejecutable de PHP y manejar otros procesos simultáneos.
El problema con esto es que cuando el código PHP terminó de ejecutar la instancia de PHP permanece en la memoria porque no hay forma de matarlo desde PHP. Entonces, si estás simulando varios hilos, puedes imaginar lo que va a pasar. Por lo tanto, sigo buscando una manera de realizar subprocesos múltiples o simularlos desde PHP. ¿Algunas ideas?
Multi-threading es posible en php
Sí, puedes hacer subprocesos múltiples en PHP con pthreads
pthreads es una API orientada a objetos que proporciona todas las herramientas necesarias para subprocesos múltiples en PHP. Las aplicaciones PHP pueden crear, leer, escribir, ejecutar y sincronizar con hilos, trabajadores y objetos con hilos.
Advertencia : la extensión pthreads no se puede utilizar en un entorno de servidor web. Por lo tanto, el subprocesamiento en PHP debe permanecer solo en aplicaciones basadas en CLI.
Prueba simple
#!/usr/bin/php
<?php
class AsyncOperation extends Thread {
public function __construct($arg) {
$this->arg = $arg;
}
public function run() {
if ($this->arg) {
$sleep = mt_rand(1, 10);
printf(''%s: %s -start -sleeps %d'' . "/n", date("g:i:sa"), $this->arg, $sleep);
sleep($sleep);
printf(''%s: %s -finish'' . "/n", date("g:i:sa"), $this->arg);
}
}
}
// Create a array
$stack = array();
//Initiate Multiple Thread
foreach ( range("A", "D") as $i ) {
$stack[] = new AsyncOperation($i);
}
// Start The Threads
foreach ( $stack as $t ) {
$t->start();
}
?>
Primer intento
12:00:06pm: A -start -sleeps 5
12:00:06pm: B -start -sleeps 3
12:00:06pm: C -start -sleeps 10
12:00:06pm: D -start -sleeps 2
12:00:08pm: D -finish
12:00:09pm: B -finish
12:00:11pm: A -finish
12:00:16pm: C -finish
Segunda carrera
12:01:36pm: A -start -sleeps 6
12:01:36pm: B -start -sleeps 1
12:01:36pm: C -start -sleeps 2
12:01:36pm: D -start -sleeps 1
12:01:37pm: B -finish
12:01:37pm: D -finish
12:01:38pm: C -finish
12:01:42pm: A -finish
Ejemplo del mundo real
error_reporting(E_ALL);
class AsyncWebRequest extends Thread {
public $url;
public $data;
public function __construct($url) {
$this->url = $url;
}
public function run() {
if (($url = $this->url)) {
/*
* If a large amount of data is being requested, you might want to
* fsockopen and read using usleep in between reads
*/
$this->data = file_get_contents($url);
} else
printf("Thread #%lu was not provided a URL/n", $this->getThreadId());
}
}
$t = microtime(true);
$g = new AsyncWebRequest(sprintf("http://www.google.com/?q=%s", rand() * 10));
/* starting synchronization */
if ($g->start()) {
printf("Request took %f seconds to start ", microtime(true) - $t);
while ( $g->isRunning() ) {
echo ".";
usleep(100);
}
if ($g->join()) {
printf(" and %f seconds to finish receiving %d bytes/n", microtime(true) - $t, strlen($g->data));
} else
printf(" and %f seconds to finish, request failed/n", microtime(true) - $t);
}
¿Qué hay de pcntl_fork?
Consulte nuestra página de manual para ver ejemplos: PHP pcntl_fork
A partir de la redacción de mi comentario actual, no sé acerca de los hilos de PHP. Vine a buscar la respuesta aquí mismo, pero una solución es que el programa PHP que recibe la solicitud del servidor web delega toda la formulación de la respuesta a una aplicación de consola que almacena su salida, la respuesta a la solicitud, a un archivo binario. y el programa PHP que lanzó la aplicación de consola devuelve ese archivo binario byte por byte como la respuesta a la solicitud recibida. La aplicación de la consola se puede escribir en cualquier lenguaje de programación que se ejecute en el servidor, incluidos los que tienen el soporte de subprocesos adecuado, incluidos los programas C ++ que utilizan OpenMP.
Un truco no confiable y sucio es usar PHP para ejecutar una aplicación de consola, "uname",
uname -a
e imprima la salida de ese comando de consola en la salida HTML para averiguar la versión exacta del software del servidor. Luego instale la misma versión exacta del software en una instancia de VirtualBox, compile / ensamble los binarios que sean totalmente independientes, preferiblemente estáticos, que desee y luego cárguelos en el servidor. A partir de ese momento, la aplicación PHP puede usar esos binarios en el rol de la aplicación de consola que tiene los subprocesos múltiples adecuados. Es una solución sucia, poco confiable, alternativa a una situación, cuando el administrador del servidor no ha instalado todas las implementaciones de lenguaje de programación necesarias en el servidor. Lo que hay que tener en cuenta es que, en cada solicitud, la aplicación PHP recibe la (s) aplicación (es) de consola, finaliza / exit / get_killed.
En cuanto a lo que los administradores de servicios de alojamiento piensan de tales patrones de uso del servidor, supongo que se reduce a la cultura. En el norte de Europa, el proveedor de servicios TIENE QUE PROPORCIONAR LO QUE SE ANUNCIÓ, y si se permitió la ejecución de los comandos de la consola, se permitió la carga de archivos no maliciosos y el proveedor de servicios tiene el derecho de detener cualquier proceso del servidor después de unos minutos o incluso de 30 segundos. A continuación, los administradores del servicio de alojamiento carecen de argumentos para presentar una queja adecuada. En Estados Unidos y Europa occidental, la situación / cultura es muy diferente y creo que existe una gran posibilidad de que en Estados Unidos y / o Europa occidental el proveedor de servicios de alojamiento se niegue a atender a los clientes de servicios de alojamiento que utilizan el truco descrito anteriormente. Esa es mi suposición, dada mi experiencia personal con los servicios de alojamiento de EE. UU. Y lo que he escuchado de otros sobre los servicios de alojamiento de Europa Occidental. A partir de la redacción de mi comentario actual (2018_09_01), no sé nada sobre las normas culturales de los proveedores de servicios de alojamiento del sur de Europa, los administradores de red del sur de Europa.
Dependiendo de lo que estés tratando de hacer, también podrías usar curl_multi para lograrlo.
El subprocesamiento múltiple significa realizar múltiples tareas o procesos simultáneamente, podemos lograr esto en php usando el siguiente código, aunque no hay una forma directa de lograr el subprocesamiento múltiple en php, pero podemos lograr casi los mismos resultados de la siguiente manera.
chdir(dirname(__FILE__)); //if you want to run this file as cron job
for ($i = 0; $i < 2; $i += 1){
exec("php test_1.php $i > test.txt &");
//this will execute test_1.php and will leave this process executing in the background and will go
//to next iteration of the loop immediately without waiting the completion of the script in the
//test_1.php , $i is passed as argument .
}
Prueba_1.php
$conn=mysql_connect($host,$user,$pass);
$db=mysql_select_db($db);
$i = $argv[1]; //this is the argument passed from index.php file
for($j = 0;$j<5000; $j ++)
{
mysql_query("insert into test set
id=''$i'',
comment=''test'',
datetime=NOW() ");
}
Esto ejecutará test_1.php dos veces simultáneamente y ambos procesos se ejecutarán en segundo plano simultáneamente, por lo que de esta manera puede lograr multiproceso en PHP.
Este chico hizo un muy buen trabajo pthreads
El subprocesamiento no está disponible en el stock de PHP, pero la programación concurrente es posible mediante el uso de solicitudes HTTP como llamadas asíncronas.
Con la configuración del tiempo de espera de rizo establecido en 1 y utilizando el mismo session_id para los procesos que desea asociar entre sí, puede comunicarse con las variables de sesión como en mi ejemplo a continuación. Con este método, incluso puede cerrar su navegador y el proceso concurrente aún existe en el servidor.
No te olvides de verificar la ID de sesión correcta de esta manera:
http://localhost/test/verifysession.php?sessionid=[the id correcto]
inicioproceso.php
$request = "http://localhost/test/process1.php?sessionid=".$_REQUEST["PHPSESSID"];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $request);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 1);
curl_exec($ch);
curl_close($ch);
echo $_REQUEST["PHPSESSID"];
process1.php
set_time_limit(0);
if ($_REQUEST["sessionid"])
session_id($_REQUEST["sessionid"]);
function checkclose()
{
global $_SESSION;
if ($_SESSION["closesession"])
{
unset($_SESSION["closesession"]);
die();
}
}
while(!$close)
{
session_start();
$_SESSION["test"] = rand();
checkclose();
session_write_close();
sleep(5);
}
verifysession.php
if ($_REQUEST["sessionid"])
session_id($_REQUEST["sessionid"]);
session_start();
var_dump($_SESSION);
closeprocess.php
if ($_REQUEST["sessionid"])
session_id($_REQUEST["sessionid"]);
session_start();
$_SESSION["closesession"] = true;
var_dump($_SESSION);
La clase Thread está disponible desde PECL pthreads ≥ 2.0.0.
Para los subprocesos múltiples HTTP utilizando GuzzleHttp (ya que pthreads puede no funcionar en aplicaciones web), consulte el blog a continuación: https://blog.madewithlove.be/post/concurrent-http-requests/
Podrías simular el enhebrado. PHP puede ejecutar procesos en segundo plano a través de popen (o proc_open). Esos procesos se pueden comunicar mediante stdin y stdout. Por supuesto, esos procesos pueden ser un programa php. Probablemente sea lo más cerca que puedas.
Puede ser que me haya perdido algo, pero exec no funcionó como asíncrono para mí en el entorno de Windows que utilicé siguiendo en Windows y funcionó a la perfección;)
$script_exec = "c:/php/php.exe c:/path/my_ascyn_script.php";
pclose(popen("start /B ". $script_exec, "r"));
Puede usar exec () para ejecutar un script de línea de comandos (como php de línea de comandos), y si canaliza la salida a un archivo, su script no esperará a que finalice el comando.
No puedo recordar la sintaxis de CLI de php, pero querría algo como:
exec("/path/to/php -f ''/path/to/file.php'' | ''/path/to/output.txt''");
Creo que un buen número de servidores de alojamiento compartido tienen exec () deshabilitado de forma predeterminada por razones de seguridad, pero vale la pena intentarlo.
Puedes tener la opción de:
- multi_curl
- Uno puede usar el comando del sistema para el mismo
- El escenario ideal es crear una función de subprocesamiento en lenguaje C y compilar / configurar en PHP. Ahora esa función será la función de PHP.
Sé que esta es una pregunta antigua, pero para las personas que realizan búsquedas, hay una extensión PECL escrita en C que ahora brinda la capacidad de subprocesos múltiples de PHP, se encuentra aquí pthreads
Sé que esto es muy antiguo, pero puede consultar http://phpthreadlib.sourceforge.net/
Admite la comunicación bidireccional entre subprocesos y también cuenta con protecciones integradas para eliminar los hilos secundarios (para prevenir huérfanos).
Si bien no puede enhebrar, tiene cierto grado de control de procesos en PHP. Los dos conjuntos de funciones que son útiles aquí son:
Funciones de control de proceso http://www.php.net/manual/en/ref.pcntl.php
Funciones POSIX http://www.php.net/manual/en/ref.posix.php
Usted podría bifurcar su proceso con pcntl_fork - devolviendo el PID del niño. Luego puede usar posix_kill para deshacerse de ese PID.
Dicho esto, si matas un proceso padre, se debe enviar una señal al proceso hijo que le indica que muera. Si el propio php no lo reconoce, puede registrar una función para administrarla y hacer una salida limpia con pcntl_signal.
el uso de hilos es posible gracias a la extensión PECLs de Pthreads
porque no usas popen
for ($i=0; $i<10; $i++) {
// open ten processes
for ($j=0; $j<10; $j++) {
$pipe[$j] = popen(''script2.php'', ''w'');
}
// wait for them to finish
for ($j=0; $j<10; ++$j) {
pclose($pipe[$j]);
}
}
pcntl_fork
no funcionará en un entorno de servidor web si tiene activado el modo seguro . En este caso, solo funcionará en la versión CLI de PHP.