简体   繁体   English

PHP-FPM和pthreads

[英]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. 我使用PHP-FPM运行Phalcon应用程序并刚刚安装了pthread,因此我可以异步开始运行任务。 I currently have pthreads working using the command line interface: 我目前使用命令行界面使用pthreads:

<?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. ^^所有这些都可以从shell运行php test.php

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. 我有一个控制器初始化一个线程对象并调用start() ,但run()方法中没有任何逻辑按原样执行。

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: 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. 我的目标是获得一个使用PHP-FPM的posix线程的hello world示例,这样我就可以开始为我的需求构建一个经过深思熟虑的解决方案。

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). 如果您使用旧版本的PHP和pthreads(<PHP7),那么线程将在没有正确设置stdout的情况下运行(因为FPM和Zend无法设置它)。

The most recent versions of pthreads (for PHP7) prohibit execution anywhere but CLI. 最新版本的pthreads(用于PHP7)禁止在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. 考虑一个控制器创建一个合理数量的线程的情况,假设是8.如果100个客户端同时请求控制器,您将要求您的硬件同时执行800内核线程,并且流量很小

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 . 如果手头的任务是发出一些异步Web请求,那么最好的方法是使用非阻塞I / O, 而不是线程

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. 如果你正确地使用了异步这个词,并且实际上意味着并行,那么你将需要为应用程序的那些部分找到另一种方法,这些部分需要与Web服务器一起扩展,以及需要并行并发的那些应用程序部分。彼此沟通。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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