byjg/phpthread

PHP 线程的 Polyfill 实现。此类支持使用 ZTS 编译的 FORK 进程和原生线程。

2.3.0 2022-03-19 00:09 UTC

This package is auto-updated.

Last update: 2024-09-05 03:33:24 UTC


README

Opensource ByJG Scrutinizer Code Quality Code Coverage Build Status

PHP 线程的 Polyfill 实现。此类支持使用 ZTS 编译的 FORK 进程和原生线程;

此类会自动检测 PHP 是否使用 ZTS (--enable-maintainer-zts 或 --enable-zts) 编译

  • 并带有 pthreads 扩展(在 Windows 上也适用)
  • 以及带有进程控制 (--enable-pcntl)

并选择最适合处理线程的处理程序。线程接口在所有线程处理程序中都是相同的。

注意事项

  • 大部分的 FORK 实现基于 "superuser" 在 "http://villavu.com/forum/showthread.php?t=73623" 发表的帖子
  • Tales Santos (tsantos84) 在 Thread ZTS 的基础上进行了贡献,创建了代码库并解决了某些特定的线程问题。谢谢!

用法

以下示例假设有类 'Foo' 和方法 'bar'

require_once('vendor/autoload.php');

// Method to be executed in a thread
$threadClousure = function ($t)
    {
        echo "Starint thread #$t" . PHP_EOL;;
        sleep(1 * rand(1, 5));
        for ($i = 0; $i < 10; $i++)
        {
            echo "Hello from thread #$t, i=$i" . PHP_EOL;
            sleep(1);
        }
        echo "Ending thread #$t" . PHP_EOL;
    
        return $t;
    };

基本线程用法

// Create the Threads passing a callable
$thread1 = new ByJG\PHPThread\Thread( $threadClousure );
$thread2 = new ByJG\PHPThread\Thread( $threadClousure );

// Start the threads and passing parameters
$thread1->execute(1);
$thread2->execute(2);

// Wait the threads to finish
$thread1->waitFinish();
$thread2->waitFinish();

// Get the thread result
echo "Thread Result 1: " . $thread1->getResult();
echo "Thread Result 2: " . $thread2->getResult();

线程池用法

你可以创建一个线程池。如果你想在池启动后排队工作,这尤其有趣。

// Create a instance of the ThreadPool
$threadPool = new \ByJG\PHPThread\ThreadPool();

// Create and queue the threads with call parameters
$threadPool->queueWorker( $threadClousure, [ 1 ]);
$threadPool->queueWorker( $threadClousure, [ 2 ]);

// Starts all the threads in the queue
$threadPool->startPool();

// Add more workers after the pool is started:
$threadPool->queueWorker( $threadClousure, [ 3 ]);
$threadPool->queueWorker( $threadClousure, [ 4 ]);

// Wait until there is no more active workers
$threadPool->waitWorkers();

// Get the return value from the thread.
foreach ($threadPool->getThreads() as $thid) {
    echo 'Result: ' . $threadPool->getThreadResult($thid) . "\n";
}

echo "\n\nEnded!\n";

关于 FORK 实现的重要说明

为了使 FORK 实现的 'getResult' 的工作,必须将设置参数传递给 Thread::setThreadHandlerArguments() 方法;

<?php

$thread = new \ByJG\PHPThread\Thread([$someinstance, $somemethod]);
$thread->setThreadHandlerArguments(
    [
        'max-size' => 0x100000,
        'default-permission' => '0700'
    ]
);

安装

只需输入:composer require "byjg/phpthread=2.3.*"

从 1.* 到 2.* 的主要更改

  • 方法 Thread::start() 已重命名为 Thread::execute()
  • 实现了 PThread 和 Fork 作为 Polyfill 类

常见问题解答

如何实例化一个方法类?

$thr = new ByJG\PHPThread\Thread(array('classname', 'methodname'));

或者

$instance = new myClass();
$thr = new ByJG\PHPThread\Thread(array($instance, 'methodname'));

依赖关系