简体   繁体   中英

PHP-FPM and pthreads

Im using PHP-FPM to run a Phalcon application and have just installed pthreads so I can start running tasks asynchronously. I currently have pthreads working using the command line interface:

<?php

/**
 * Author: Abu Ashraf Masnun
 * URL: http://masnun.me
 */

class WorkerThreads extends Thread
{
    private $workerId;

    public function __construct($id)
    {
        $this->workerId = $id;
    }

    public function run()
    {
        usleep(2000000); // 2 seconds
        echo "Worker {$this->workerId} ran" . PHP_EOL;
    }
}

// Worker pool
$workers = [];

// Initialize and start the threads
foreach (range(0, 5) as $i) {
    $workers[$i] = new WorkerThreads($i);
    $workers[$i]->start();
}

// Let the threads come back
foreach (range(0, 5) as $i) {
    $workers[$i]->join();
}

die('finished');

^^ all of that works running php test.php from the shell.

But I am unable to get this example to work using the fast process manager. I have a controller initializing a thread object and calling start() , but none of the logic in the run() method executes as it should.

Controller:

<?php

public function indexAction()
{

$threads=[];
for ( $i = 0; $i < 2; $i++ )
{
    $threads[$i] = new AsyncThread();
    $a = $threads[$i]->start();
    $b = $threads[$i]->isStarted();
    Phalcon\DI::getDefault()->get('logger')->log(json_encode($a));
    Phalcon\DI::getDefault()->get('logger')->log(json_encode($b));
}
for ( $i = 0; $i < 2; $i++ )
{
    $threads[$i]->join();
}
die('done');

AsyncThread.php:

<?php

class AsyncThread extends Thread
{

    public function __construct()
    {
        Phalcon\DI::getDefault()->get('logger')->log( 'construct' );
    }

    public function run()
    {
        usleep(2000000); // 2 seconds
        Phalcon\DI::getDefault()->get('logger')->log( 'running' );
    }

}

When this runs my logs show:

[Tue, 17 Nov 15 22:10:43 +0000][INFO][][] construct
[Tue, 17 Nov 15 22:10:43 +0000][INFO][][] true
[Tue, 17 Nov 15 22:10:43 +0000][INFO][][] true
[Tue, 17 Nov 15 22:10:43 +0000][INFO][][] construct
[Tue, 17 Nov 15 22:10:43 +0000][INFO][][] true
[Tue, 17 Nov 15 22:10:43 +0000][INFO][][] true

I expect to see 'running' log asynchronously, but it never logs at all.

My goal is to just get a hello world example of posix threads working with PHP-FPM so I can begin building a well thought out solution for my needs.

If you are using an old version of PHP and pthreads (< PHP7), then the threads will run without having stdout set correctly (because FPM and Zend have no way to set it).

The most recent versions of pthreads (for PHP7) prohibit execution anywhere but CLI.

There is no way to use threads sensibly at the frontend of your application.

Consider the case of a controller that creates a reasonable number of threads, let's say 8. If 100 clients request the controller concurrently, you will be asking your hardware to execute 800 kernel threads concurrently, with a tiny amount of traffic.

This kind of architecture cannot scale.

You have persistently used the word asynchronous in place of parallel, this makes me think that you probably don't want threads at all.

If the task at hand is to make some asynchronous web requests, then the best way to do that is with non-blocking I/O, not threads .

If you are using the word asynchronous incorrectly, and do actually mean parallel, then you will need to find another way for those parts of the application that are required to scale with the web server, and those parts of the application that require parallel concurrency to communicate with each other.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM