Programación en paralelo con PHP

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