Realizar algunas tareas puede ser algo lento, por lo que a veces es necesario ejecutar procesos en paralelo para agilizar la ejecución de un script. PHP no permite programación concurrente, por lo cual hay que simularlo, y para ello es necesario la utilización de sockets.
El método es sencillo, se crean dos sockets y se comprueba que hayan acabado de ejecutarse:
// Ejecuta un proceso en un socket
function JobStartAsync($server, $url, $port=80,$conn_timeout=30, $rw_timeout=86400) {
$errno = '';
$errstr = '';
set_time_limit(0);
$fp = fsockopen($server, $port, $errno, $errstr, $conn_timeout);
if (!$fp) {
echo "$errstr ($errno)
\n";
return false;
}
$out = "GET $url HTTP/1.1\r\n";
$out .= "Host: $server\r\n";
$out .= "Connection: Close\r\n\r\n";
stream_set_blocking($fp, false);
stream_set_timeout($fp, $rw_timeout);
fwrite($fp, $out);
return $fp;
}
// Devuelve falso si el socket está desconectado o un string (que puede ser vacio) si está conectado
function JobPollAsync(&$fp) {
if ($fp === false) return false;
if (feof($fp)) {
fclose($fp);
$fp = false;
return false;
}
return fread($fp, 10000);
}
// Ejecución inicial
// Se ejecutan dos procesos cualquiera j1 y j2
$fp1 = JobStartAsync('localhost','/jobs/j1.php');
$fp2 = JobStartAsync('localhost','/jobs/j2.php');
while (true) {
sleep(1);
$r1 = JobPollAsync($fp1);
$r2 = JobPollAsync($fp2);
if ($r1 === false && $r2 === false) break;
echo "r1 = $r1
";
echo "r2 = $r2
";
flush(); @ob_flush();
}
echo "Jobs Complete
";
El autor profundiza algo más y comenta también cómo se resolvería el método divide y vencerás.
Siempre hay que tener cuidado cuando se programa en paralelo ya que podemos tener problemas al acceder simultáneamente a un recurso compartido.
Easy Parallel Processing in PHP
Muchas gracias, muy interesante, sin duda lo utilizaré.
Por cierto, corrige el titulo del post.
Siempre es interesante saber de estas minilibrerÃas, ya que aunque en mi caso uso CodeIgniter, de vez en cuando viene bien
Paco, espero que te sea útil
Josepzin, yo también uso CodeIgniter, pero en algunos casos sencillos, usar CI es demasiado y suelo tirar de estas librerÃas