oliverde8/asynchronous-jobs

轻松执行新的PHP实例,就像线程一样。

1.0.6 2016-03-14 18:52 UTC

This package is auto-updated.

Last update: 2024-09-16 03:06:07 UTC


README

PHP AsynchronousJobs 是一个小型库,允许在主代码并行运行PHP代码。在某种程度上,它就像线程一样工作,但它并没有使用适当的系统库来实现这一点。这是一个变通方案

Build Status Latest Stable Version Total Downloads Latest Unstable Version License

该库是为了在没有安装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()以获取最新信息。这样做不是为了同步大量数据,而是为了跟踪进度或类似的东西。