PHP-多线程带有pthreads的函数
我目前正在使用pthreads在一个非常苛刻的函数上实现多线程。到目前为止,我已经做到了:PHP-多线程带有pthreads的函数,php,multithreading,pthreads,Php,Multithreading,Pthreads,我目前正在使用pthreads在一个非常苛刻的函数上实现多线程。到目前为止,我已经做到了: class Operation extends Thread { public function __construct($arg) { $this->arg = $arg; } public function run() { if ($this->arg) { $parameters = $this->arg; echo my_f
class Operation extends Thread {
public function __construct($arg) {
$this->arg = $arg;
}
public function run() {
if ($this->arg) {
$parameters = $this->arg;
echo my_function($parameters[0],$parameters[1]);
}
}
}
$stack = array();
foreach ($work as $operation) { $stack[] = new Operation($operation); };
foreach ($stack as $t) { $t->start(); };
它直接输出结果。
我希望将结果一个接一个地存储在数组中(以相同的顺序存储会更好),但这当然不起作用:
class Operation extends Thread {
public function __construct($arg) {
$this->arg = $arg;
}
public function run() {
if ($this->arg) {
$parameters = $this->arg;
$results[] = my_function($parameters[0],$parameters[1]);
}
}
}
$stack = array();
foreach ($work as $operation) { $stack[] = new Operation($operation); };
foreach ($stack as $t) { $t->start(); };
var_dump($results);
任何帮助都将不胜感激
详情:
- my_函数输出一个UTF-8字符串
现在您的$results\u已排序!享受吧 基本问题是数组不是线程安全的,pthreads在所有线程对象上提供类似数组的接口;这意味着您可以在多线程上下文中使用线程对象代替数组
<?php
function demanding(...$params) {
/* you have parameters here */
return array(rand(), rand());
}
class Task extends Collectable {
public function __construct(Threaded $result, $params) {
$this->result = $result;
$this->params = $params;
}
public function run() {
$this->result[] =
demanding(...$this->params);
}
protected $result;
protected $params;
}
$pool = new Pool(16);
$result = new Threaded();
while (@$i++<16) {
$pool->submit(
new Task($result, $argv));
}
$pool->shutdown();
var_dump($result);
?>
没有内置的方法来进行多线程排序,因此最简单的方法是在线程完成后对结果进行排序。您能在此处显示
my\u function()
code吗?几乎不能。它很大,所有的变量都是法语。为了方便读者,我重构了这部分代码。你有没有具体的想法?它输出一个UTF-8文本字符串。因此,您的意思是希望工作线程一个接一个地同步输出结果,而不是在它们完成时输出结果?这是最好的,但如果以牺牲速度为代价的话就不行了。我可以输出一个带有结果的索引号,然后对所有内容进行排序。好吧,你不能强制线程同步返回结果。这使得它们毫无用处,它们需要在完成时返回结果,而你不知道什么时候会发生。这就是为什么您必须给它们一个索引,并与它们同步,收集它们的输出、索引,然后在调用它们的主上下文中对结果进行排序。sleep
将完全暂停cpu核心1秒。您还假设线程将在这一秒内完成。您可以使用while循环来检查线程是否已完成,如果已完成,则将它们连接起来,而不是手动阻塞。我个人喜欢的方法是使用事件循环(libev,libuv)和异步方法-我通知主上下文某个特定线程已完成,而等待进程是非阻塞的,它允许在线程进行处理时使用CPU内核。你是对的。我正在研究。这可能也分享了一些见解:如果我没有弄错的话,while循环应该生成sleep()指令,直到所有线程都关闭。它既不美观又低效,这就是为什么我在寻找一个解决方案,但我认为它是可行的……问题是在普通PHP中,我们需要浪费CPU周期,因为它没有任何类型的代码可以挂接到操作系统的事件接口(IOCP
on-Win,epoll
kqueue
on*nix)。但是,使用while($thread->isRunning())
至少可以知道它何时完成。使用sleep
时,您猜测一秒钟左右的时间就足以让线程完成。while
和sleep
都不雅观,因为它们在浪费资源。这就是我个人使用libev
事件循环的原因,我从线程内部向事件循环发送通知,告知它们已经完成。它是非阻塞的。“我是PHP pthreads的作者。”嗯,我想我没有更好的答案了,非常感谢您的帮助!从现在起,我打算经常使用pthreads,您是否可以推荐一些在线资源来帮助我学习如何高效、优雅地使用pthreads?我研究了pthreads Github中的示例,这正是帮助我编写上述代码的原因,但我不得不说这并不容易!
<?php
function demanding(...$params) {
/* you have parameters here */
return array(rand(), rand());
}
class Task extends Collectable {
public function __construct(Threaded $result, $params) {
$this->result = $result;
$this->params = $params;
}
public function run() {
$this->result[] =
demanding(...$this->params);
}
protected $result;
protected $params;
}
$pool = new Pool(16);
$result = new Threaded();
while (@$i++<16) {
$pool->submit(
new Task($result, $argv));
}
$pool->shutdown();
var_dump($result);
?>