在PHP运行的异步功能 [英] Running async function in 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屋!