Processamento Paralelo com PHP

Introdução

Neste artigo vamos demonstrar uma forma alternativa de como gerenciar processos paralelos no PHP. O PHP não possui uma forma nativa de threads. Existe a extensão pthreads (PECL) que permite trabalhar com multi-threading. Porém nem sempre podemos contar com essa opção dependendo do ambiente nos servidores de produção. Eu mesmo já presenciei diversos ambientes em produção onde não é possível instalar novas extensões facilmente. Além de tudo, essa extensão, pthreads, necessita que o PHP seja re-compilado a partir do código fonte na maioria das distribuições Linux.

O procedimento descrito neste artigo, explora o que é chamado de system calls, usando o S.O. Linux. Portanto, os procedimentos não irão funcionar em ambiente Windows.

De quebra, os exemplos deste artigo também poderão ser facilmente aproveitados para criação de um script “start/stop/restart

Criando um novo processo

Para criarmos um novo processo no Linux, enviando a execução para background, a partir de um script PHP, podemos fazer a seguinte chamada usando a função exec:

exec("nohup php app.php >/dev/null 2>&1 & echo $!", $output);

O que é interessante observar no comando acima:

  • A execução do processo esta sendo enviada para background.
  • nohup – ignora os sinais de interrupção durante a execução do script.
  • echo $! – retorna o PID do processo iniciado. Podemos resgatar o PID na variável $output.

Podemos criar uma função que simplesmente que executa o comando, colocando o processo em segundo plano, e retornando o PID do mesmo para que possamos monitorá-lo posteriormente:

<?php

$command = "php script.php";
$pid = run($command);

echo $pid; // imprimr o PID

function run($cmd) {
        $cmd = sprintf("nohup %s >/dev/null 2>&1 & echo $!", $cmd);
        exec($cmd, $output);
        return(trim($output[0]));
}

Parar auxiliar no controle dos processos já executados, podemos criar uma função que checa se o PID esta no ar, e uma outra função para finalizar o processo caso seja necessário:


// verifica se determinado processo esta rodando
function isRunning($pid)  {
        $command = "/bin/ps -p $pid";
        exec($command, $output);

        if(isset($output[1])) {
                return true;
        }
        return false;
}

// finaliza processo
public function kill($pid) {
        $command = "/bin/kill $pid";
        exec($command);
}

Por final, disponibilizo uma classe que gerencia essas funções, onde você pode extendê-la de acordo com a complexidade da sua necessidade. Lembrando que este mecanismo funciona apenas em ambiente Linux.

class Process {

        // roda processo em backgound e retorna PID
        public function run($cmd) {
                $cmd = sprintf("nohup %s >/dev/null 2>&1 & echo $!", $cmd);
                exec($cmd, $output);
                return(trim($output[0]));
        }

        // verifica se processo esta rodando
        public function isRunning($pid)  {
                $command = "/bin/ps -p $pid";
                exec($command, $output);

                if(isset($output[1])) {
                        return true;
                }

                return false;
        }

        // finaliza processo
        public function kill($pid) {
                $command = "/bin/kill $pid";
                exec($command);
        }
}
Please follow and like us:

Comments

    • mm By Douglas V. Pasqua

    • mm By Douglas V. Pasqua

Follow

Get every new post on this blog delivered to your Inbox.

Join other followers: