最近研究了PHP的多线程扩展parallel,记录了基本使用过程,供以后查阅
安装
- PHP版本最低需要7.2.0
- PHP必须是ZTS
- PHP版本>=7.2
pecl install parallel-1.1.4
- PHP版本>=8.0
pecl install parallel
函数式API
在硬件和操作系统约束允许的情况下,任务将立即开始并行执行,而不会不必要地创建运行时。对于大多数应用程序,应首选函数式API。
parallel\bootstrap
parallel\bootstrap(string $file): void
以引导文件为parallel\run提供运行时
parallel 创建线程的时候跟主线程是不共享代码,新线程不能原来代码里的类,可以传入一个引导文件,类似于autoload之类的自动加载文件
parallel\run
在线程中执行任务
示例
<?php
$threadFunction = function (string $str){
echo $str . "\n";
};
for ($i=0; $i < 10; $i++) {
$args = [ 0 => $i];
\parallel\run($threadFunction, $args);
}
2.
<?php
# index.php
\parallel\bootstrap('function.php');
$threadFunction = function (string $str){
echo $str . "\n";
test();
};
for ($i=0; $i < 10; $i++) {
$args = [ 0 => $i];
\parallel\run($threadFunction, $args);
}
<?php
# function.php
function test(){
echo 'test' ."\n";
}
3. laravel中使用
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use App\Models\Table;
class ParallelTestCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'parallel:test';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Command description';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
\parallel\bootstrap(__DIR__.'/../../../parallel.php');
$threadFunction = function (string $str){
var_dump(Table::query()
->where('id',$str)
->value('id'));
};
for ($i=0; $i < 10; $i++) {
$args = [ 0 => $i];
\parallel\run($threadFunction, $args);
}
}
}
<?php
# parallel.php 位于项目根目录
$app = require_once __DIR__.'/bootstrap/app.php';
$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);
$kernel->bootstrap();
其他
- 在硬件和操作系统约束允许的情况下,任务将立即开始并行执行,而不会不必要地创建运行时。对于大多数应用程序,应首选功能API
- 加载的引导文件会应用到所有线程
- 没有提供关闭线程的方法
- 扩展提供了其他的方式来解决以上两个问题