PHP中缺少“开箱即用”的多线程功能,因此发明了许多实现方式,包括扩展
pthreads ,
AzaThread (CThread)甚至PHP开发人员
自己的开发。
对我而言,主要缺点是这些解决方案太多了“麻烦”-并不总是需要在线程和父进程之间交换信息或节省资源。 始终应该具有快速,经济高效地解决问题的能力。
我想提前保留一个秘密,以防止在这篇文章中公开大秘密-对于初学者来说,这很可能是该语言的秘密,所以我决定发布它只是因为我自己遇到了问题,并且还没有找到现成的解决方案,所以我自己做了一种多线程仿真。
因此,任务是处理进入脚本的大量数据。 我的任务是处理文本信息的JSON数组,消化该脚本必须从中收集的信息,这对于PostgreSQL来说是同样大的提交。
首先,我们收集父文件中的数据:
index.php
数组大小在400mb左右波动(后来减少到〜50mb),并且所有信息都是文本信息。 不难估计所有内容的消化速度,并且考虑到脚本每15分钟在cron上运行一次,并且计算能力如此之高,因此性能受到很大影响。
接收到数据之后,您可以估计它们的数量,并在必要时计算每个CPU内核的必要线程数,或者可以简单地确定将有4个线程并计算每个线程的行数:
index.php
值得一提的是-这样的“正面”计算不会通过每个流的元素数量给出确切的结果。 需要更有可能简化计算。
现在最重要的是-我们为每个线程创建任务并运行它。 我们将执行此“前额”操作-为第二个文件-thread.php创建一个任务。 它将充当“流”,接收一系列元素以独立于主脚本进行处理和启动:
index.php
passthru()函数用于运行控制台命令,但是脚本将等待每个命令完成。 为此,我们将启动命令包装在一组语句中,这些语句将启动进程并立即不返回任何内容,启动进程,父进程不会停止等待每个子进程执行:
不幸的是,我不能肯定地说出这里到底发生了什么-我熟悉的Linuxoid向我建议了一组参数。 如果您能在评论中破译这种魔力,我将不胜感激,并将补充该帖子。
文件thread.php:
$start = $argv[1]; $stop = $argv[2]; for ($i = $start; $i <= $stop; $i++) {
通过这种非常简单的方法,您可以在PHP中实现多线程仿真。
如果我们将整个示例简化为干燥输出,那么我认为这听起来像是:命令行中的父线程启动子进程,告诉子进程要处理哪些信息。
当我说“仿真”时,我的意思是说,使用这种实现方法无法在线程之间或父子线程之间交换信息。 如果事先知道不需要这种特征是合适的。