besanek / threads
PHP中的虚拟线程
dev-master
2014-05-13 11:16 UTC
Requires (Dev)
- nette/tester: 1.0.*
This package is auto-updated.
Last update: 2024-09-10 21:29:09 UTC
README
##为什么?
- 简单使用
- 无需任何PHP扩展
安装
最佳安装方式是使用Composer
$ composer require besanek/threads:@dev
##使用方法
基本
很简单!
use Besanek\Threads; // ... $executable = new Threads\Executables\PhpExecutable('path/to/script.php'); $job = new Threads\Job($executable); $job->run();
你可以编写自己的可执行程序,提供运行bash脚本、原生应用程序、内联PHP代码以及任何你想要的东西。只需实现Besanek\Threads\IExecutable接口。
让我们处理工作
有时我们需要读取输出,有时需要写入一些输入
$executable = new Threads\Executables\PhpExecutable('path/to/repeat.php'); $job = new Threads\Job($executable); $job->run(); $job->write('Hello'); echo $job->read(); //Hello;
警告!子进程在另一个进程中运行,因此在读写时可能会有延迟。在这种情况下,不能保证
read()返回'Hello'。如果子进程比当前脚本慢,就会发生这种情况。解决方案是等待循环,如下所示。while(empty($output = $job->read())) {}
### It's OK or NOT?
How to react to end of the subscript? Callbacks!
```php
$ok = function () { echo "OK" };
$fail = function () { echo "FAIL" };
$job = new Threads\Job($executable, $ok, $fail);
两个回调都传递了3个参数。stdout、stderr和exitcode。
$ok = function ($stdout) { echo $stdout }; $fail = function ($stdout, $stderr, $exitcode) { echo "FAILS with exitcode: " . $exitcode . " and error: " . $stderr; };
注意:回调在
isDone()方法中处理,默认情况下在对象析构时调用。这可能太晚了。如果您需要更早地处理回调,请手动运行isDone()方法。理想情况下,在子进程仍在运行的情况下,在一个等待循环中。while($job->isDone() === false) {}
### At the end is here management
Imagine, you need resize thousand of pictures. It's ideal for threads! But, if I creates thousand of subprocesses, I wastes all sources on my machine. Is there solution?
**Yes!** `Besanek\Threads\Runner`.
You can add set of jobs and limit the number of threads.
```php
$images = // do some black magic
$runner = new Threads\Runner(50); //Max 50 subprocess
foreach($images as $image) {
$arguments = '-size=1000x1000 -output output/path/' . $image->name . '--source '.$image->path;
$executable = new Threads\Executables\PhpExecutable('path/to/resize.php', $arguments);
$job = new Threads\Job($executable);
$runner->addJob($job);
$runner->process();
}
信息:方法
process()有一个参数,用于确定作业队列是否完全完成。因此,如果您调用process(true),整个队列将逐步运行,但会阻塞主进程,直到所有作业完成。默认情况下,在运行者的析构函数中调用。
警告!只有在
process()方法中运行和完成作业。因此,如果您忘记调用它,作业将等待直到脚本结束。