从PHP7开始,多线程编原有的pthreads已经不在维护,而是使用parallel替代。
由于是新的模块,样例代码很少,这里总结一个简单的代码和详细的备注供大家参考。
编译和安装
parallel需要启用ZTS(Zend Thread Safety)的PHP构建版本(使用"--enable-zts"选项,或者在PHP 8.0.0之前的非Windows系统上使用"--enable-maintainer-zts"选项)。
1)下载PHP 7.2或8以上版本的源代码
2)下载parallel源代码,解压到php源代码的exc目录下,将parallel目录名命名为"parallel"
3)在php源码目录下按顺序执行如下命令:
bash
./buildconf --force
./configure --enable-zts --enable-parallel --enable-fpm --with-curl --with-openssl
make
make install
其中配置选项--enable-zts --enable-parallel是必要的,其他根据自己需要增减。
安装完毕后,可以看到模块已经安装:
bash
php -m
[PHP Modules]
...
parallel
...
使用样例
php
<?php
use \parallel\{Runtime, Future, Channel, Events};
/**
* 测试并发执行的函数。
* 该函数模拟并发执行多个任务,并跟踪每个任务的执行情况,直到所有任务完成。
*
* @param int $concurrency 并发执行的任务数量。
*/
function testConcurrency(int $concurrency) {
// 定义一个睡眠函数,用于模拟耗时操作。
$sleeper = function (int $seconds) {
sleep($seconds);
return $seconds;
};
// 初始化用于存储未来结果的数组和运行时对象的数组。
$futureList = [];
$runtimeList = [];
// 创建指定数量的运行时对象。
for ($i = 0; $i < $concurrency; $i++) {
$runtimeList[] = new Runtime();
}
// 并发执行任务。
foreach ($runtimeList as $i => $runtime) {
$seconds = rand(1, 10);
$futureList[$i] = $runtime->run($sleeper, [$seconds]);
}
// 监控所有任务直到完成。
echo "loop... \n";
while (true) {
// 检查每个任务的状态。
foreach ($futureList as $i => $runtime) {
if ($runtime->done()) {
$value = $runtime->value();
echo "ThreadId: $i Sleep: $value seconds (End)\n";
unset($runtimeList[$i]);
}
}
// 打印当前运行中的任务数量,并休眠一段时间后继续检查。
echo count($runtimeList) . " thread is running... \n";
sleep(2);
// 如果没有运行中的任务,则结束监控。
if (empty($runtimeList)) break;
}
}
$concurrency = 5;
testConcurrency($concurrency);
?>