在PHP运行的异步功能 [英] Running async function in php

查看:113
本文介绍了在PHP运行的异步功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是有可能创造一些PHP类,它可以异步运行的功能呢?以下是我迄今所做的:

 类工作者继承Thread
{
    保护$ asyncFun;
    保护$ paramsArray;    公共职能的run(){
        $ asyncFun(/ *参数去这里* /)
    }    公共职能setAsyncFunction($ FUNC,$ paramsArr)
    {
        $这个 - > asyncFun = $ FUNC;
        $这个 - > paramsArray = $ paramsArr;
    }
}

下面是我想称之为:

  $工人=新员工();
$工人─> setAsyncFunction(富,[一,B]);
$工人::开始();


解决方案

pthreads的最近版本支持闭包作为成员,使code很简单:

 < PHP
类Background继承Thread {    公共职能__construct($赎回调用,数组的$ args = []){
        $这个 - >调用= $调用;
        $这个 - > ARGS =的$ args;
    }    公共职能的run(){
        call_user_func_array($这个 - >打电话,$这个 - >参数);
    }    保护$调用;
    受保护的$ args;
}$背景=新的背景(函数($贺卡){
    的printf(%S \\ n,$贺卡);
}, [你好,世界]);
$背景 - >启动();
$背景 - >加入();命名函数($贺卡){
    的printf(%S \\ n,$贺卡);
}$背景=新的背景(命名,[再见世界]);
$背景 - >启动();
$背景 - >加入();
?>

不过,这是可怕的,很难想象这是太饿了,它需要它自己的线程任何功能。

您已经开始打倒思想对路,你应该重用上下文并创建一个工作线程,pthreads的拥有这一切内置的。

更明智code。使用内置类看起来更像是:

 < PHP
类Background扩展螺纹{    公共职能__construct($赎回调用,数组的$ args = []){
        $这个 - >调用= $调用;
        $这个 - > ARGS =的$ args;
    }    公共职能的run(){
        call_user_func_array($这个 - >打电话,$这个 - >参数);
    }    保护$调用;
    受保护的$ args;
}$池=新池(4);$ pool->提交(新背景(函数($贺卡){
    的printf(%S \\ n,$贺卡);
}, [你好,世界]));$ pool->关闭();
?>

但是,这仍然不处理返回值。我假设你想检索使用的呼叫结果的泳池,在这种情况下,code看起来更像是:

 < PHP
类Background扩展螺纹{    公共职能__construct($赎回调用,数组的$ args = []){
        $这个 - >调用= $调用;
        $这个 - > ARGS =的$ args;
    }    公共职能的run(){
        $这个 - >同步(函数(){
            $这个 - >结果= call_user_func_array
                ($这个 - >打电话,$这个 - >参数);
            $这个 - >通知();
        });
    }    公共职能的getResult(){
        返回$这个 - >同步(函数(){
            而(!使用isset($这个 - >结果))
                $这个 - >等待();
            返回$这个 - >的结果;
        });
    }    保护$调用;
    受保护的$ args;
    保护$结果;
}$池=新池(4);$电话=新的背景(函数($贺卡){
    返回的sprintf(%S \\ n,$贺卡);
}, [你好,世界]);$ pool->提交($电话);回声$ call->的getResult();$ pool->关闭();
?>

正如你所看到的,到背景::的getResult通话将导致等待,直到结果可用调用的背景下,这可能会或可能不会是可取的,但使一个很好的例子。

is it possible to create some php class which can run functions asynchronously? Here is what I have done so far:

class Worker extends Thread
{
    protected  $asyncFun;
    protected $paramsArray;

    public function run() {
        $asyncFun(/*parameters go here*/)
    }

    public function setAsyncFunction($func, $paramsArr)
    {
        $this->asyncFun = $func;
        $this->paramsArray = $paramsArr;
    }
}

Here is how I want to call it:

$worker = new Worker();
$worker->setAsyncFunction(foo, ["a", "b"]);
$worker::start();

解决方案

Recent versions of pthreads support closures as members, making the code very simple:

<?php
class Background extends Thread {

    public function __construct(callable $call, array $args = []) {
        $this->call = $call;
        $this->args = $args;
    }

    public function run() {
        call_user_func_array($this->call, $this->args);
    }

    protected $call;
    protected $args;
}

$background = new Background(function($greeting){
    printf("%s\n", $greeting);
}, ["Hello World"]);
$background->start();
$background->join();

function named($greeting) {
    printf("%s\n", $greeting);
}

$background = new Background("named", ["Goodbye World"]);
$background->start();
$background->join();
?>

However, this is horrible, it's hard to imagine any function that is so hungry that it requires a thread of it's own.

You have started down the right path with the thought that you should reuse the context and create a worker thread, pthreads has all of this built in.

More sensible code using built in classes looks more like:

<?php
class Background extends Threaded {

    public function __construct(callable $call, array $args = []) {
        $this->call = $call;
        $this->args = $args;
    }

    public function run() {
        call_user_func_array($this->call, $this->args);
    }

    protected $call;
    protected $args;
}

$pool = new Pool(4);

$pool->submit(new Background(function($greeting){
    printf("%s\n", $greeting);
}, ["Hello World"]));

$pool->shutdown();
?>

But this still doesn't deal with a return value. I'll assume that you want to retrieve the result of calls made using the Pool, in that case the code looks more like:

<?php
class Background extends Threaded {

    public function __construct(callable $call, array $args = []) {
        $this->call = $call;
        $this->args = $args;
    }

    public function run() {
        $this->synchronized(function(){
            $this->result = call_user_func_array
                ($this->call, $this->args);
            $this->notify();
        });
    }

    public function getResult() {
        return $this->synchronized(function(){
            while (!isset($this->result))
                $this->wait();
            return $this->result;
        });
    }

    protected $call;
    protected $args;
    protected $result;
}

$pool = new Pool(4);

$call = new Background(function($greeting){
    return sprintf("%s\n", $greeting);
}, ["Hello World"]);

$pool->submit($call);

echo $call->getResult();

$pool->shutdown();
?>

As you can see, a call to Background::getResult will result in the calling context waiting until a result is available, this may or may not be desirable, but makes for a good example.

这篇关于在PHP运行的异步功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆