PHP多进程模式?

PHP多进程模式?,php,multithreading,asynchronous,Php,Multithreading,Asynchronous,存在哪种设计模式来实现一些PHP进程的执行和一个PHP进程中结果的收集 背景: 我在PHP中有许多大型树(>10000个条目),必须对其运行递归检查。我想减少运行时间 您可以从php脚本启动另一个脚本(使用exec)来进行处理。将状态更新保存在文本文件中,然后父线程可以定期读取该文本文件 注意:为了避免php等待exec'd脚本完成,请将输出通过管道传输到文件: exec('/path/to/file.php | output.log'); 或者,您可以使用函数派生脚本。这使用了一个php脚本

存在哪种设计模式来实现一些PHP进程的执行和一个PHP进程中结果的收集

背景:

我在PHP中有许多大型树(>10000个条目),必须对其运行递归检查。我想减少运行时间

您可以从php脚本启动另一个脚本(使用
exec
)来进行处理。将状态更新保存在文本文件中,然后父线程可以定期读取该文本文件

注意:为了避免php等待
exec
'd脚本完成,请将输出通过管道传输到文件:

exec('/path/to/file.php | output.log');
或者,您可以使用函数派生脚本。这使用了一个php脚本,当分叉时可以检测它是父脚本还是子脚本,并相应地进行操作。有一些函数可以发送/接收信号,以便在父/子系统之间进行通信,或者您可以将子系统日志记录到某个文件中,然后从该文件读取父系统日志

从手册页面:

$pid = pcntl_fork();
if ($pid == -1) {
     die('could not fork');
} else if ($pid) {
     // we are the parent
     pcntl_wait($status); //Protect against Zombie children
} else {
     // we are the child
}

这可能是一个考虑使用A的好时机,即使你在一台机器上运行它。

< P>使用Web或CLI?

如果您使用web,您可以将该部分集成到中,然后可以利用JAVA多线程的优势

但我不知道Quercus有多可靠。我还建议使用一种消息队列并重构代码,这样就不需要作用域

也许您可以将代码重新构建为Map/Reduce模式。然后可以在Hadoop中运行PHP代码,然后可以通过几台机器对处理进行集群


我不知道它是否有用,但我遇到了另一个项目,叫做。它还用于对PHP进程进行集群。如果Hadoop不是您想要的方式,我想您也可以将其与reduce脚本结合起来。

如果您的目标是最短时间,那么解决方案描述起来很简单,但实现起来却不那么简单

您需要找到一种划分工作的模式(您在这方面的问题中没有提供太多信息)

然后使用一个主进程,让孩子们来做这项工作。通常,您使用的进程总数应介于
n
2n
之间,其中
n
是机器的核心数

假设这些数据将存储在文件中,您可能会考虑使用非阻塞IO来最大化吞吐量。不这样做将使您的大部分进程花费时间等待磁盘。PHP提供了可能对您有所帮助的功能。请注意,使用它并不是一件小事

如果您决定不使用
选择
,增加进程的数量可能会有所帮助



关于
pcntl
函数:我已经用它们编写了一个deamon(一个合适的命令,包括分叉、更改会话id、运行用户等),它是我编写的最可靠的软件之一。因为它会为每个任务生成工作人员,即使其中一个任务中有bug,也不会影响其他任务。

这个问题似乎有点困惑

我想减少绝对执行时间

你是说经过的时间吗?当然,使用正确的数据结构将提高吞吐量,但对于给定的数据结构,算法的最小顺序是绝对的,与如何实现算法无关

存在哪种设计模式来实现

设计模式是代码所属的东西,不是编写程序的模板,也是课程设计的有用工具。从模式开始并使代码适合它本身就是一种反模式

如果不了解更多关于数据及其结构的信息,没有人能够回答这个问题,但是,提高效率的关键驱动因素将是用于实现树的数据结构。如果运行时间很重要,那么当然可以考虑并行执行,但是也值得考虑使用不同的工具执行操作-数据库对于处理大型数据集进行了高度优化,但是请注意,在关系数据库中描述树的明显方法在隔离子树和遍历树时效率非常低

对于亚当关于分叉的建议,你回答说:

我“听说”pcntl不是一个好的解决方案。有什么经验吗

你在哪里听到的?当然,从CGI或mod_php调用的脚本分叉是一个坏主意,但从命令行这样做没有错。确实有一个长期运行PHP进程的google(请注意,有很多不好的信息)。您编写的代码会因底层操作系统的不同而有所不同—您没有说明这一点

我认为,通过确定需要检查树的哪些部分,并且只检查这些部分,并在更新树时触发检查,或者至少将节点标记为“脏”节点,可以解决大部分性能问题

您可能会发现以下内容很有帮助:


C.

您可以使用更高效的数据结构,例如btree。我用过一次Java,但没有用PHP。您可以尝试以下脚本:,它是btree的一个实现

如Michael所说,如果这还不够,您可以使用Hadoop实现Map/Reduce模式。我不会分叉PHP进程,它似乎对性能没有帮助

就我个人而言,我会使用PHP作为客户端,并将所有内容都放在Hadoop中。本教程可能会有所帮助:

另一个解决方案是使用Btree的Java实现:。JDBM是一个使用Btree+数据结构的对象数据库。然后,您可以通过使用web服务公开数据或使用Quercus直接访问数据来使用PHP进行搜索 有一个新的(自2012年以来)PHP扩展可用:。它可以通过安装

PHP代码中的简单实现:从线程扩展到类。添加一个
run()
方法并执行
start()
方法

<?php
// Example from http://www.phpgangsta.de/richtige-threads-in-php-einfach-erstellen-mit-pthreads
class AsyncOperation extends Thread
{
    public function __construct($threadId)
    {
        $this->threadId = $threadId;
    }
 
    public function run()
    {
        printf("T %s: Sleeping 3sec\n", $this->threadId);
        sleep(3);
        printf("T %s: Hello World\n", $this->threadId);
    }
}
 
$start = microtime(true);
for ($i = 1; $i <= 5; $i++) {
    $t[$i] = new AsyncOperation($i);
    $t[$i]->start();
}
echo microtime(true) - $start . "\n";
echo "end\n";

... 写一个C扩展名
>php pthreads.php
0.041301012039185
end
T 1: Sleeping 3sec
T 2: Sleeping 3sec
T 3: Sleeping 3sec
T 4: Sleeping 3sec
T 5: Sleeping 3sec
T 1: Hello World
T 2: Hello World
T 3: Hello World
T 4: Hello World
T 5: Hello World