我使用PHP-FPM运行Phalcon应用程序并刚刚安装了pthread,因此我可以异步开始运行任务。我目前使用命令行界面运行pthread:
<?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');
^^所有这些都可以从shell运行php test.php
。
但我无法让这个例子使用快速流程管理器。我有一个控制器初始化一个线程对象并调用start()
,但run()
方法中没有一个逻辑执行它应该。
控制器:
<?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' );
}
}
当这运行我的日志显示:
[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
我希望异步看到“正在运行”的日志,但它根本不会记录。
我的目标是获得一个使用PHP-FPM的posix线程的hello world示例,这样我就可以开始为我的需求构建一个经过深思熟虑的解决方案。
答案 0 :(得分:6)
如果您使用旧版本的PHP和pthreads(&lt; PHP7),则线程将在没有正确设置stdout的情况下运行(因为FPM和Zend无法设置它)。
最新版本的pthreads(适用于PHP7)禁止在CLI以外的地方执行。
无法在应用程序的前端明智地使用线程。
考虑一个控制器创建合理数量的线程的情况,让我们说8.如果100个客户端同时请求控制器,您将要求您的硬件同时执行800内核线程,使用微小的流量。
这种架构无法扩展。
你一直使用异步这个词取代并行,这让我觉得你可能根本不想要线程。
如果手头的任务是发出一些异步Web请求,那么最好的方法是使用非阻塞I / O,而不是线程。
如果您正确使用异步这个词,并且实际上意味着并行,那么您需要找到应用程序中需要与Web服务器一起扩展的那些部分的另一种方法,以及需要应用程序的那些部分并行并发以相互通信。