oliverde8 / asynchronous-jobs
轻松执行新的PHP实例,就像线程一样。
Requires
- php: >=5.4.0
Requires (Dev)
- phpunit/phpunit: 4.*
README
PHP AsynchronousJobs 是一个小型库,允许在主代码并行运行PHP代码。在某种程度上,它就像线程一样工作,但它并没有使用适当的系统库来实现这一点。这是一个变通方案
该库是为了在没有安装php pthreads扩展的情况下在Windows和Linux系统上工作而创建的。**该库不能被视为线程的替代品**!该库的工作方式并不优化为此目的。
它是专为并行执行长期任务而构建的。一个好的例子就是在主脚本向用户提供信息的同时下载文件。该库旨在用于命令行工具和守护进程。
原因
尽管pthreads很棒,但许多服务器都没有安装它,因此添加对该依赖项可能导致阻塞。在这种情况下,该库是为ml-expansion项目构建的,该项目用于满足人们希望有“即用即得”解决方案的需求。这个库就是针对这个问题的。
如果您需要定期运行一些线程,而不想添加对pthreads的依赖项,这个库可能正是您所需要的。
常见问题解答
https://github.com/oliverde8/PHP-AsynchronousJobs/wiki/Faq
使用方法
首先您需要创建一个任务
class Sleep extends Job
{
public $time = 1;
/**
* Method called by the new instance to run the job.
*
* @return mixed
*/
public function run()
{
sleep($this->time);
}
/**
* Method called by the original instance when the job has ran.
*
* @return mixed
*/
public function end()
{
$time = $this->time;
echo "I end after : $time!";
}
}
然后您可以创建一个任务
$job1 = new Sleep();
$job1->sleep = 3;
让我们也创建第二个任务。
$job2 = new Sleep();
$job2->sleep = 2;
现在执行这些任务
$job1->start()
$job2->start()
// And wait for the end
sleep (4);
您应该看到第一个消息是"I end after 2",然后是消息"I end after 3"
等待进行中的任务
一旦您开始了一些任务,您可能需要等待它们完成。
所以一旦您开始您的任务
$job1->start()
$job2->start()
// ....
您可以使用wait all
JobRunner::getInstance()->waitForAll(1);
这将阻塞您的实例,直到所有任务完成执行。waitForAll接受睡眠时间作为参数。因此,如果您知道您的任务需要几天时间才能运行,您可以将睡眠时间增加到几分钟,以防止I/O过度使用。
您也可能希望只有一个任务完成
$job1->wait();
进程将阻塞,直到任务1完成。
进行Curl请求。
这是一个非常简单的实现,用于执行curl查询。**应该改进**!但好吧,它可以在打开任务执行时构建。
$curlJob = new Curl();
$curlJob->setMethod('GET');
$curlJob->setUrl('http://jsonplaceholder.typicode.com/posts');
$curlJob->start();
JobRunner::getInstance()->waitForAll(1);
$info = $curlJob->getCurlInfo();
$response = $curlJob->getResponse()
当然,您可以传递一些参数,并执行POST查询。
使用回调
您还可以在任务上放置回调,以便在任务完成后调用函数。
public function testCallback()
{
$curlJob = new CallbackCurl();
$curlJob->setMethod('GET');
$curlJob->setUrl('http://jsonplaceholder.typicode.com/posts');
$curlJob->setCallback(array($this, '_testCallbackCallback'));
$curlJob->start();
JobRunner::getInstance()->waitForAll(1);
echo "You should then see this !\n"
}
public function _testCallbackCallback(Job $curlJob)
{
echo "You should first see this !\n";
}
自定义设置
您必须调用以下自定义设置
JobRunner::getInstance()
在运行任何任务之前,这必须是您的第一个调用!!
这些方法可以接受以下参数
- $id 允许您在多个进程之间共享实例,如果您不理解,请将其留为null,通常不需要更改。
- $phpExecutable php可执行文件的路径,在Windows上可能会出现问题,在Linux上,仅php就足够了。
- $tmpPath 存放用于同步进程的临时文件的路径。它需要由进程可写。
须知事项
被忽略的变量
在作业启动时,您在作业中设置的所有变量将被传输到新的执行(线程),然后在作业完成后,使用作业的新值进行更新。这些变量可能是私有的或公共的,它们将被序列化并传递到新的执行。一旦执行完成,它们将被再次序列化并发送回主执行。
在某些情况下,我们可能希望在主进程或新的执行中只有值可用。所有以双下划线("_")开头的变量在传输过程中将被忽略。
示例
private $__test = 'tt';
待办事项:未来
- Redis支持(非常酷且速度快)
- 备注:我需要将当前JobRunner的内容分离,以便将数据管理部分与逻辑分离。
- 信号量支持
- 作业与实例之间的共享内存
- 当作业希望共享一些新数据时,将执行
->push(),而在主进程中,我们将对作业调用->pop()以获取最新信息。这样做不是为了同步大量数据,而是为了跟踪进度或类似的东西。
- 当作业希望共享一些新数据时,将执行