不知道为什么还没有一个"hack"标签(抱歉在PHP中列出),但是…
我想知道它/如何有可能使用多线程行走数组使用多线程/异步功能的hack。我真的不需要这个,但它是一个好奇的东西,可能会有用。
我已经看了"Hack"的异步特性的文档
http://docs.hhvm.com/manual/en/hack.async.php这有点难。
这是我想做(或看到完成)的基本想法:
a)将数组拆分为x段,并在x个"线程"上处理它或者b)创建x个线程,每个线程处理最新可用的项目。当线程处理该项时,它要求父线程处理一个新的项。Hack不做"线程",但同样用async函数
表示。基本上,最终目标是快速优化标准foreach块以在多个线程上运行,因此需要最小的代码更改,并且还可以查看hack可以做什么以及它是如何工作的。
我想出了一些代码作为示例,但我认为我完全理解错了。
class ArrayWalkAsync
{
protected $array;
protected $threads = Array();
protected $current_index = 0;
protected $max_index;
protected $threads = 4;
public function array_walk($array)
{
$this->array = $array;
$this->max_index = count($array) - 1;
$result = Array();
for ($i=0;$i<$this->threads;$i++)
{
$this->threads[] = new ArrayWalkThread();
}
$continue = true;
while($continue)
{
$awaitables = Array();
for ($i=0;$i<$this->threads;$i++)
{
$a = $this->proccesNextItem($i);
if ($a)
{
$this->threads[] = $a;
} else {
$continue = false;
}
}
// wait for each
foreach ($awaitables as $awaitable_i)
{
await awaitable_i;
// do something with the result
}
}
}
protected function proccesNextItem($thread_id)
{
if ($this->current_index > $this->max_index)
{
return false;
}
$a = new ArrayWalkItem();
$a->value = $this->array[$this->current_index];
$a->index = $this->current_index;
$this->current_index++;
return $this->threads[$thread_id]->process($a,$this);
}
public function processArrayItem($item)
{
$value = $item->value;
sleep(1);
$item->result = 1;
}
}
class ArrayWalkThread
{
async function process($value,$parent): Awaitable<?ArrayWalkItem>
{
$parent->processArrayItem($a);
}
}
class ArrayWalkItem
{
public $value;
public $result;
}
Hack的异步函数不会做你想做的事。在Hack中,异步函数不是线程。这是一种隐藏IO延迟和数据获取的机制,而不是一次执行多个计算。(这与c#中相同,Hack特性就是从c#中派生出来的。)
这篇关于异步函数的博文有一个很好的解释:
几个月来,Hack已经有了一个叫做async的功能,它允许编写多任务协作代码。这有点类似于线程,因为多个代码路径是并行执行的,但是它避免了多线程代码常见的锁争用问题,因为在任何给定时刻只实际执行一个部分。
"那有什么用?"我听到你这样问。您仍然被绑定到一个CPU上,因此执行代码应该花费相同的时间,对吗?从技术上讲,这是正确的,但是脚本代码执行并不是导致应用程序延迟的唯一原因。其中最大的一部分可能来自等待后端数据库响应查询。
[…]
当[http]调用忙于等待响应时,没有理由不能做其他事情,甚至可能发出更多请求。数据库查询也是如此,它可能花费同样长的时间,甚至文件系统访问也比网络快,但仍然会引入几毫秒的延迟时间,这些都加起来了!
很抱歉在这一点上造成混淆——您不是唯一一个试图以这种方式错误地使用异步的人。当前的文档在解释这一点上做得糟糕。我们正在对文档进行改造;当前的草案做得比较好,但是在我们启动新文档之前,我要去归档一个任务,以确保它非常清晰。