"walk" PHP 使用多线程(异步)和 hack (HHVM) 的数组
"walk" a PHP array using multithreaded (async) with hack (HHVM)
不确定为什么还没有 "hack" 标签(很抱歉在 PHP 中列出),但是...
我想知道 it/how 是否可以使用 hack 的 multithreaded/async 功能使用多线程遍历数组。我真的不需要这个,但这是一种好奇心,可能会有用。
我查看了 "Hack" 的异步功能的文档
http://docs.hhvm.com/manual/en/hack.async.php
有点难。
这是我想做的(或看完成的)的基本想法:
a) 将数组拆分为 x 个部分并在 x "threads" 上进行处理
或 b) 创建 x 个线程,每个线程处理最新的可用项目,即。当线程处理该项目时,它会要求父线程处理一个新项目。 Hack 不做 "threads",但同样由一个 asyc 函数表示
基本上,最终目标是在多线程上将标准 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 功能的来源。)
This blog post on async functions有很好的解释:
For several months now, Hack has had a feature available called async which enables writing code that cooperatively multitasks. This is somewhat similar to threading, in that multiple code paths are executed in parallel, however it avoids the lock contention issues common to multithreaded code by only actually executing one section at any given moment.
“What’s the use of that?”, I hear you ask. You’re still bound to one CPU, so it should take the same amount of time to execute your code, right? Well, that’s technically true, but script code execution isn’t the only thing causing latency in your application. The biggest piece of it probably comes from waiting for backend databases to respond to queries.
[...]
While [an http] call is busy sitting on its hands waiting for a response, there’s no reason you shouldn’t be able to do other things, maybe even fire off more requests. The same goes for database queries, which can take just as long, or even filesystem access which is faster than network, but can still introduce lag times of several milliseconds, and those all add up!
对于这一点上的混淆,我们深表歉意——您并不是唯一一个尝试以这种方式错误地使用异步的人。当前的文档对此进行了 糟糕的 解释。我们正在对文档进行修改; current draft 做得更好一些,但我要提交一个任务以确保它在我们启动新文档之前 crystal 清楚。
不确定为什么还没有 "hack" 标签(很抱歉在 PHP 中列出),但是...
我想知道 it/how 是否可以使用 hack 的 multithreaded/async 功能使用多线程遍历数组。我真的不需要这个,但这是一种好奇心,可能会有用。
我查看了 "Hack" 的异步功能的文档
http://docs.hhvm.com/manual/en/hack.async.php
有点难。
这是我想做的(或看完成的)的基本想法:
a) 将数组拆分为 x 个部分并在 x "threads" 上进行处理 或 b) 创建 x 个线程,每个线程处理最新的可用项目,即。当线程处理该项目时,它会要求父线程处理一个新项目。 Hack 不做 "threads",但同样由一个 asyc 函数表示
基本上,最终目标是在多线程上将标准 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 功能的来源。)
This blog post on async functions有很好的解释:
For several months now, Hack has had a feature available called async which enables writing code that cooperatively multitasks. This is somewhat similar to threading, in that multiple code paths are executed in parallel, however it avoids the lock contention issues common to multithreaded code by only actually executing one section at any given moment.
“What’s the use of that?”, I hear you ask. You’re still bound to one CPU, so it should take the same amount of time to execute your code, right? Well, that’s technically true, but script code execution isn’t the only thing causing latency in your application. The biggest piece of it probably comes from waiting for backend databases to respond to queries.
[...]
While [an http] call is busy sitting on its hands waiting for a response, there’s no reason you shouldn’t be able to do other things, maybe even fire off more requests. The same goes for database queries, which can take just as long, or even filesystem access which is faster than network, but can still introduce lag times of several milliseconds, and those all add up!
对于这一点上的混淆,我们深表歉意——您并不是唯一一个尝试以这种方式错误地使用异步的人。当前的文档对此进行了 糟糕的 解释。我们正在对文档进行修改; current draft 做得更好一些,但我要提交一个任务以确保它在我们启动新文档之前 crystal 清楚。