contextualcode / threads
允许使用 pthreads PHP 扩展在多个线程中运行任务
v1.0.0
2019-02-28 16:46 UTC
Requires
- ext-pthreads: >=3.0.0
This package is not auto-updated.
Last update: 2024-09-21 18:42:12 UTC
README
本包是 pthreads
扩展的包装器。提供了一种简化方式来运行多个线程中的任务并收集结果。
要求
唯一的要求是安装并启用最新版本(v3)的 pthreads
PHP 扩展。请在此处查看其要求 这里。
安装
- 需要该包
composer require contextualcode/threads
- 完成!现在您可以定义自定义任务。这些任务应扩展
ContextualCode\Threads\Thread
类,并实现do
方法。请使用ContextualCode\Threads\Runner
来运行它们。
用法
假设,我们有一个简单的任务:生成随机数并睡眠 1 秒。我们还想构建一个 Symfony 4 Command
,该命令将使用 10
个并发线程运行该任务 10
次。
首先,我们需要在
src/Task.php
中定义任务类<?php namespace App; use ContextualCode\Threads\Thread; class Task extends Thread { public function do() { $number = rand(0, 1000); sleep(1); return $number; } }
现在,我们需要创建一个
src/Commond/TestThreadsCommand.php
,它将使用10
个线程运行Task
<?php namespace App\Command; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Debug\ErrorHandler; use App\Task; use ContextualCode\Threads\Runner; class TestThreadsCommand extends Command { protected static $defaultName = 'app:test-threads'; protected function configure() { $this->setDescription('Tests contextualcode/threads package'); } protected function execute(InputInterface $input, OutputInterface $output) { $concurrentThreadsNumber = 10; $timeToRunTask = 10; // Run the tasks $start = microtime(true); $runner = new Runner($concurrentThreadsNumber); for ($i = 1; $i <= $timeToRunTask; $i++) { $runner->addTask(new Task()); } $numbers = $runner->process(); // Output results $runtime = microtime(true) - $start; $avg = array_sum($numbers) / count($numbers); $output->writeln('Random numbers: ' . implode(', ', $numbers)); $output->writeln('Average number: ' . number_format($avg, 2)); $output->writeln('Execution time: ' . number_format($runtime, 2)); } }
- 并运行命令
$ php bin/console app:test-threads Random numbers: 916, 98, 219, 999, 323, 205, 259, 979, 328, 871 Average number: 519.70 Execution time: 1.13
- 如果在命令运行期间出现
Serialization of 'Closure' is not allowed
错误,这可能是由于 这个错误。只需在TestThreadsCommand
命令的execute
方法顶部添加以下代码。它将看起来像这样protected function execute(InputInterface $input, OutputInterface $output) { if ($phpHandler = set_exception_handler(function() {})) { restore_exception_handler(); if (is_array($phpHandler) && $phpHandler[0] instanceof ErrorHandler) { $phpHandler[0]->setExceptionHandler(null); } } ... }