是否可以创建一些可以异步运行函数的php类?以下是我到目前为止所做的事情:
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;
}
}
以下是我想要的方式:
$worker = new Worker();
$worker->setAsyncFunction(foo, ["a", "b"]);
$worker::start();
答案 0 :(得分:5)
最新版本的pthreads支持闭包作为成员,使代码非常简单:
<?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();
?>
但是,这太可怕了,很难想象任何功能如此饥饿以至于它需要一个自己的线程。
你已经开始沿着正确的道路开始思考你应该重用上下文并创建一个工作线程,pthreads已经内置了所有这些。
使用内置类的更合理的代码看起来更像:
<?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();
?>
但这仍然没有处理回报价值。我假设您要检索使用Pool
进行的调用的结果,在这种情况下,代码看起来更像:
<?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();
?>
正如您所看到的,对Background::getResult
的调用将导致调用上下文等待,直到结果可用,这可能是也可能不是,但这是一个很好的例子。
答案 1 :(得分:2)