Vida de un Programador

Experiencias, ideas y programas

Threading en PHP

Minecraft PHP ClientHoy, actualizando el cliente de Minecraft que desarollo, encontré que ciertas partes podrían funcionar mejor “en segundo plano”.

Estas partes son la lectura de los datos enviados por el servidor y la descompresión-parseo de chunks (trozos de terreno).
PHP no tiene soporte para distintos “hilos”, pero soporta hacer “fork” de los procesos. No obstante, esto solo esta soportado en linux.

Vamos a usar la funcion “pcntl_fork()” para separa un proceso en dos partes.

Necesitaba que funcionara asi:

  • Separar los procesos, para que los dos hiciesen cosas distintas a la vez sin depender uno del otro directamente.
  • Permitir la comunicacion entre ambos procesos, para pasar entre ellos datos
  • Que si el proceso padre (el que lo origino) muere, el hijo no se quede “zombie”

Esto hice al final:

$sockets = array();
socket_create_pair(strtoupper(substr(PHP_OS,0,3)) == "WIN" ? AF_INET:AF_UNIX, SOCK_STREAM, 0, $sockets);
$parent_sock = $sockets[0];
$child_sock = $sockets[1];
unset($sockets);
$pid = pcntl_fork();
if($pid == -1){
	console("[-] Failed to fork");
	define("THREADED", false);
}elseif($pid){ //Parent
	socket_close($child_sock);
	define("THREADED", true);
	define("CHILD", false);
}else{ //Child
	define("CHILD", true);
    socket_close($parent_sock);
    forking_runtime($child_sock);
    posix_kill(getmypid(),9);
}

Lo primero que hace este codigo es crear un par de sockets unidos entre si mediante la funcion socket_create_pair(). El nombre del tipo de socket es diferente en Windows y linux, asi que por si acaso en un futuro existe fork en Windows, lo dejo aqui.

Luego, mediante la funcion pcntl_fork(), separo el proceso en dos. Mas bien, creo una copia exacta.
Si el valor de retorno es -1, significa que el “fork” no ocurrio. SI es 0, significa que somos el proceso hijo. Si es un numero, somos el padre, y ese valor es el PID (Process IDentifier) del proceso hijo.

A partir de ahora solo hay que enviar entre los procesos la informacion que se requiera, e introducir un “timeout” de que si no recibimos entrada en, por ejemplo, 10 segundos, el proceso hijo se cierra.

Espero que esto les sirva si quieren realizar algun proyecto como un servidor o asi😉

Responder

Por favor, inicia sesión con uno de estos métodos para publicar tu comentario:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: