PHP 中的多线程/多任务处理前端线程化为什么前端的线程是一个坏主意?我们能做些什么呢?

2022-08-31 00:40:42

在PHP中,我们通常在不考虑服务器功能的情况下进行编码。现在,即使是PC也拥有多个内核,并且还可以处理64位数据。据我所知,PHP引擎本身已经过优化,可以利用多个内核。我们程序员如何进一步优化代码以利用多个内核。

换句话说,我想知道哪些技术可以教我编写代码,这些代码更有可能被php引擎考虑处理并行性。

我不是要求任何用户定义/开源的排队方法,而是以这样一种方式编写相同的代码,即它利用多核并且工作得更快。

如果您已经在做这样的事情,请提出您的想法并分享您的经验。

我希望我们应该有办法进一步优化代码。


答案 1

PHP 自 2000 年 5 月 22 日 PHP4 首次发布以来,已有很长一段时间的线程模型。

前端线程化

在Web应用程序的前端创建用户线程没有任何意义;它极难扩展。Apache Worker MPM二进制文件和mod_php使用的每个客户端模型的线程并不是你真正想要用来为网站服务的东西,当然,如果你正在使用它,你不想创建额外的线程来直接响应任何Web请求。

为什么前端的线程是一个坏主意?

您可能经常听到开发人员说前端的线程没有意义,而没有提供这种断言的理由。当您学会以所需的方式思考系统时,问题就变得很明显了:

如果客户端脚本创建 8 个线程以直接响应 Web 请求,并且 100 个客户端同时请求该脚本,则您请求硬件同时执行 800 个线程。

CPU的外观和工作方式必须非常不同,才能使这成为一个好主意。

我们能做些什么呢?

有进取心的解决方案很可能有一个面向公众的PHP网站,但系统的实际大脑是用语言编写的,这些语言对构建有进取心的解决方案所需的东西有很好的支持,例如Java,C#,C++或任何当天的语言。

您应该以相同的方式使用 pthreads;通过设计其组件彼此分离的系统,仅通过设计良好的高性能(RPC)API连接,使得设计多线程架构所固有的复杂性与面向公众的网站完全隔离,以及此类网站所需的简单,可扩展的设置。

您现在可以黑兹代码

让我们从Hello World开始:

<?php
class My extends Thread {
    public function run() {
        printf("Hello World\n");
    }
}

/* create a new Thread */
$my = new My();

/* start the Thread */
$my->start();

/* do not allow PHP to manage the shutdown of your Threads */
/* if a variable goes out of scope in PHP it is destroyed */
/* joining explicitly ensures integrity of the data contained in an objects */
/* members while other contexts may be accessing them */
$my->join();
?>

很无聊,但我希望你读;)

因此,在实际的系统中,您并不想如此明确地创建线程,您肯定只想将任务提交给某些执行器服务,所有复杂的系统,从其多任务要求的意义上说,我见过使用这样的东西......

<?php
class My extends Threaded {
    public function run() {
        printf("Hello World from %s#%lu\n",
            __CLASS__, Thread::getCurrentThreadId());   
    }
}

/* create a Pool of four threads */
/* threads in a pool are created when required */
$pool = new Pool(4);

/* submit a few tasks to the pool */
$tasks = 100;
while ($tasks--) {
    $pool->submit(new My());
}

/* shutting down the pool is tantamount to joining all workers */
/* remember what I said about joining ? */
$pool->shutdown();
?>

我已经给了你非常简短的解释复杂的事情,你应该努力阅读所有你能读到的:

在这里可以找到许多例子:https://github.com/krakjoe/pthreads/tree/master/examples

免责声明:使用线程的服务器架构没有什么问题,但是当你开始创建其他线程的那一刻,你就限制了它的可扩展性和按设计执行的能力,我可以想象设计良好的架构确实具有在前端线程的能力,但这不是一件容易的事情。此外,当涉及到高性能Web目标应用程序时,线程并不是工具箱中唯一的东西。研究您的所有选择。


答案 2

使用PHP的最常见方法是通过Apache等多进程Web服务器运行它。这意味着即使PHP本身不是多核感知的,操作系统也会尽最大努力在可用的CPU之间平衡Web服务器进程创建的负载。

如果你有一个独立的长时间运行的PHP程序,你单独在一个进程中运行,你将不得不考虑线程化或将程序分解成不同的进程,以便能够利用多个CPU。哪个更好/更容易取决于您的特定情况:将任务分解成碎片的难易程度,需要多少进程间/线程通信,需要多少同步等。

虽然标准PHP发行版本身似乎没有线程支持,但有一些扩展,如php-pthreads,允许使用本机API。pthreads

要将长时间运行的 PHP 程序划分为多个进程,可以使用 pcntl 库或proc_* 系列函数。至于IPC..同样,这取决于您的需求。


推荐