允许使用 pthreads PHP 扩展在多个线程中运行任务

v1.0.0 2019-02-28 16:46 UTC

This package is not auto-updated.

Last update: 2024-09-21 18:42:12 UTC


README

本包是 pthreads 扩展的包装器。提供了一种简化方式来运行多个线程中的任务并收集结果。

要求

唯一的要求是安装并启用最新版本(v3)的 pthreads PHP 扩展。请在此处查看其要求 这里

安装

  1. 需要该包
     composer require contextualcode/threads
    
  2. 完成!现在您可以定义自定义任务。这些任务应扩展 ContextualCode\Threads\Thread 类,并实现 do 方法。请使用 ContextualCode\Threads\Runner 来运行它们。

用法

假设,我们有一个简单的任务:生成随机数并睡眠 1 秒。我们还想构建一个 Symfony 4 Command,该命令将使用 10 个并发线程运行该任务 10 次。

  1. 首先,我们需要在 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;
         }
     }
    
  2. 现在,我们需要创建一个 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));
         }
     }
    
  3. 并运行命令
     $ 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
    
  4. 如果在命令运行期间出现 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);
             }
         }
        ...
     }