pthreads

Introdução

pthreads é uma API orientada a objetos que fornece todas as ferramentas necessárias para multithreading em PHP. Aplicações PHP podem criar, ler, escrever, executar e sincronizar com Threads, Workers e objetos Threaded.

Aviso

Esta extensão é considerada sem manutenção e inoperante.

Dica

Considere usar parallel no lugar.

Aviso

A extensão pthreads não pode ser usada em um ambiente de servidor web. Threading em PHP é, portanto, restrito apenas a aplicações baseadas em CLI.

Aviso

pthreads (v3) só pode ser usado com PHP 7.2+: Isso ocorre porque o modo ZTS não é seguro em 7.0 e 7.1.

A classe Threaded forma a base da funcionalidade que permite a operação dos pthreads. Expõe métodos de sincronização e algumas interfaces úteis para o programador.

A classe Thread permite que threads sejam criadas simplesmente estendendo-as e implementando um método run. Quaisquer membros podem ser gravados e lidos por qualquer contexto com uma referência ao thread. Qualquer contexto também pode executar qualquer método público e protegido. O corpo do método run será executado em um thread separado quando o método Thread::start() da implementação for chamado a partir do contexto que o criou. Somente o contexto que cria um thread pode iniciar e ingressar nele.

A classe Worker tem um estado persistente e estará disponível a partir da chamada para Thread::start() (um método herdado) até que o objeto saia do escopo ou seja explicitamente desligamento (via Worker::shutdown()). Qualquer contexto com uma referência ao objeto worker pode empilhar tarefas no Worker (via Worker::stack()), onde essas tarefas serão executadas pelo worker em um thread separado. O método run de um objeto worker será executado antes de qualquer objeto na pilha do worker, permitindo a inicialização de recursos que os objetos a serem executados possam necessitar.

A classe Pool é usada para criar um grupo de workers para distribuir objetos Threaded entre eles. É a maneira mais fácil e eficiente de usar vários threads em aplicações PHP.

Cuidado

A classe Pool não estende a classe Threaded e, portanto, objetos baseados em pool são considerados objetos PHP normais. Como tal, as suas instâncias não devem ser partilhadas entre diferentes contextos.

A classe Volatile é nova no pthreads v3. É usado para denotar propriedades Threaded mutáveis de classes Threaded (uma vez que agora são imutáveis por padrão). Também é usado para armazenar arrays PHP em contextos Threaded.

A sincronização é uma habilidade importante durante o threading. Todos os objetos que o pthreads cria possuem sincronização integrada na forma (que será familiar aos programadores java) de Threaded::wait() e Threaded::notify(). Chamar Threaded::wait() em um objeto fará com que o contexto espere por outro contexto para chamar Threaded::notify() no mesmo objeto. Este mecanismo permite uma sincronização poderosa entre objetos Threaded em PHP.

Cuidado

Quaisquer objetos destinados ao uso nas partes multithread de sua aplicação devem estender Threaded.

Armazenamento de dados: Como regra geral, qualquer tipo de dados que possa ser serializado pode ser usado como membro de um objeto Threaded, ele pode ser lido e escrito a partir de qualquer contexto com uma referência ao objeto Threaded. Nem todo tipo de dados é armazenado em série; os tipos básicos são armazenados em sua forma verdadeira. Tipos complexos, arrays e objetos que não são encadeados são armazenados serialmente; eles podem ser lidos e gravados no Threaded Object a partir de qualquer contexto com uma referência. Com exceção dos Objetos Threaded, qualquer referência usada para definir um membro de um Objeto Threaded é separada da referência no Objeto Threaded; os mesmos dados podem ser lidos diretamente do Objeto Threaded a qualquer momento por qualquer contexto com uma referência ao Objeto Threaded.

Membros Estáticos: Quando um novo contexto é criado (Thread ou Worker), geralmente eles são copiados, mas recursos e objetos com estado interno são anulados (por questões de segurança). Isso permite que eles funcionem como uma espécie de armazenamento local de threads. Por exemplo, ao iniciar o contexto, uma classe cujos membros estáticos incluem informações de conexão para um servidor de banco de dados, e a própria conexão, terá apenas as informações de conexão simples copiadas, não a conexão. Permitir que o novo contexto inicie uma conexão da mesma forma que o contexto que a criou, armazenando a conexão no mesmo local sem afetar o contexto original.

Cuidado

Quando print_r, var_dump e outras funções de depuração de objetos são executadas, elas não incluem proteção recursiva.

Nota: Recursos: As extensões e funcionalidades que definem recursos em PHP são completamente despreparadas para este tipo de ambiente; O pthreads prevê que os recursos sejam compartilhados entre contextos; no entanto, para a maioria dos tipos de recursos, isso deve ser considerado inseguro. Deve-se ter extrema cautela e cuidado ao compartilhar recursos entre contextos.

Cuidado

No ambiente em que o pthreads é executado, algumas restrições e limitações são necessárias para fornecer um ambiente estável.

adicionar nota

Notas de Usuários 4 notes

up
27
anonymous at example dot com
8 years ago
Here are some notes regarding PHP pThreads v3 that I have gathered:
-namespace: It does not understand namespaces. 
-globals: It won't serialize GLOBALS at all! And will not register new ones.
-classes: It registers new classes okay.
-functions: Will not register ANY functions - they must all be in static classes. It does understand PHP native functions. 
-consts: previous constants will transfer over. Don't make any new ones thou!
-pThreads only work in CLI - of course!
-If a thread crashes it automatically gets recreated.
-In order to 'force kill' any thread the parent must be killed. Or wait until all other tasks queued are complete and then terminate.
-Anything registered in a pThread does not seem to join the main thread ... which is good!
-pThreads seem to be very powerful on multi-core environments, just need to be careful on system resources... it can and will lock up a system if mis-configured.
-Finally, finding help for PHP pThreads is slim to none... especially v3!

Good luck!
up
9
meadowsjared at gmail dot com
5 years ago
In this example, it shows how to use a threaded with a pool to get an array of results, using pThreads v3.2.1 and php 7.3.23

<?php
class TestWork extends Threaded {
//updated version that works with pThreads v3.2.1 and php 7.3.23
    protected $complete;
    //$pData is the data sent to your worker thread to do it's job.
    public function __construct($pData) {
        //transfer all the variables to local variables
        $this->complete = false;
        $this->testData = $pData;
    }
    //This is where all of your work will be done.
    public function run() {
        usleep(2000000); //sleep 2 seconds to simulate a large job
        $this->complete = true;
    }
    public function isDone() {
        return $this->complete;
    }
}
class ExamplePool extends Pool {
    public $data = array(); // used to return data after we're done
    private $numTasks = 0; // counter used to know when we're done
    /**
     * override the submit function from the parent
     * to keep track of our jobs
     */
    public function submit(Threaded $task) {
        $this->numTasks++;
        parent::submit($task);
    }
    /**
     * used to wait until all workers are done
     */
    public function process() {
        // Run this loop as long as we have
        // jobs in the pool
        while (count($this->data) < $this->numTasks) {
            $this->collect(function (TestWork $task) {
                // If a task was marked as done
                // collect its results
                if ($task->isDone()) {
                    $tmpObj = new stdclass();
                    $tmpObj->complete = $task->complete;
                    //this is how you get your completed data back out [accessed by $pool->process()]
                    $this->data[] = $tmpObj;
                }
                return $task->isDone();
            });
        }
        // All jobs are done
        // we can shutdown the pool
        $this->shutdown();
        return $this->data;
    }
}
$pool = new ExamplePool(3);
$testData = 'asdf';
for($i=0;$i<5;$i++) {
    $pool->submit(new TestWork($testData));
}
$retArr = $pool->process(); //get all of the results
echo '<pre>';
print_r($retArr); //return the array of results (and maybe errors)
echo '</pre>';
?>
up
9
jasonrlester at yahoo dot com
12 years ago
Note that this extension *is* a high level implementation of POSIX threads, including on Windows (which is why pthreadsV*.dll is required)
up
6
admin at deosnet dot com
11 years ago
Hello,

WARNING : When using Stackable objects in callable functions by your Threads, you must be very careful if you use it as an array. Indeed, if you do not copy your Stackable "array" in a local variable, the execution time can drop drastically !

Also, if you want to modify an array() in a function, you will also store in a local variable in order that your array is in a thread-safe context.
To Top