Skip to content

Instantly share code, notes, and snippets.

@fjugaldev
Created April 14, 2020 08:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fjugaldev/ff2772a9859f118cc254affbe1ff3334 to your computer and use it in GitHub Desktop.
Save fjugaldev/ff2772a9859f118cc254affbe1ff3334 to your computer and use it in GitHub Desktop.
<?php
namespace Threading;
use Threading\Task\BaseTask as AbstractTask;
/**
* Multi-thread / task manager
*/
class ThreadManager
{
/**
* Array asociativo de pid con hilos activos
* @var array
*/
protected $_activeThreads = array();
/**
* Número máximo de hilos hijos que pueden ser creados por un hilo padre
* @var int
*/
protected $maxThreads = 5;
/**
* Class constructor
*
* @param int $maxThreads Número máximo de hilos hijos que pueden ser creados por un hilo padre
*/
public function __construct($maxThreads = 5)
{
$this->maxThreads = $maxThreads;
}
/**
* Inicia el aministrador de hilos
*
* @param AbstractTask $task Tarea a iniciar
*
* @return void
*/
public function start(AbstractTask $task)
{
$pid = pcntl_fork();
if ($pid == -1)
{
throw new \Exception('[Pid:' . getmypid() . '] No se pudo clonar (fork) el proceso');
}
// Hilo Padre
elseif ($pid)
{
$this->_activeThreads[$pid] = true;
// Logrado el numero máximo de hilos permitidos
if($this->maxThreads == count($this->_activeThreads))
{
// Proceso Padre : Chequea que todos los hijos hayan terminado (Para evadir los procesos hilos zombies)
while(!empty($this->_activeThreads))
{
$endedPid = pcntl_wait($status);
if(-1 == $endedPid)
{
$this->_activeThreads = array();
}
unset($this->_activeThreads[$endedPid]);
}
}
}
// Hilo Hijo
else
{
$task->initialize();
// On success
if ($task->process())
{
$task->onSuccess();
}
else
{
$task->onFailure();
}
// Mata el proceso hijo una vez que haya terminado de ejecutarse
posix_kill(getmypid(), 9);
}
pcntl_wait($status, WNOHANG);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment