”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > PHP 中的并发和并行

PHP 中的并发和并行

发布于2024-07-31
浏览:566

Concurrency and Parallelism in PHP

并发和并行是现代编程中的基本概念,允许应用程序通过交错执行(并发)或同时执行(并行)同时执行多个任务。 PHP 主要以其同步执行模型而闻名,现已发展为通过各种技术支持这些范例。

PHP 的标准执行模型

PHP 传统上遵循同步执行模型,尤其是在典型的 Web 服务器设置中与 Apache 一起使用时。在此模型中,每个 HTTP 请求都由单个 PHP 进程处理。处理请求涉及的步骤包括:

  1. Apache 接收 HTTP 请求并将其转发给 PHP。
  2. PHP 在单个线程中从头到尾执行脚本
  3. PHP 将输出 返回给 Apache,然后 Apache 将响应发送回客户端。

此模型确保简单性和易于理解,但对于需要并行执行或同时处理多个任务的任务来说可能会变得低效。

PHP 中并发性和并行性的演变

随着 Web 应用程序变得越来越复杂,PHP 中并发和并行执行的需求也在增长。让我们探索 PHP 提供的实现这些范例的技术。

1. 同步代码

同步代码是最简单的执行形式,其中任务一个接一个地执行。

echo "Synchronous Code Example:\n";
function synchronousFunction() {
    for ($i = 0; $i 



在此示例中,循环的每次迭代按顺序执行,迭代之间有一秒的延迟。这种方法很简单,但对于可以从并行执行中受益的 I/O 密集型或 CPU 密集型任务来说效率较低。

2. 分叉进程

分叉创建一个与原始进程(父进程)同时运行的新进程(子进程)。这对于并行任务很有用。

echo "\nForking Process Example:\n";
function forkProcess() {
    $pid = pcntl_fork();
    if ($pid == -1) {
        die('could not fork');
    } else if ($pid) {
        echo "Parent Process: PID $pid\n";
        pcntl_wait($status); // Protect against Zombie children
    } else {
        echo "Child Process: Hello from the child process!\n";
        exit(0);
    }
}
forkProcess();

在此代码中,pcntl_fork() 创建一个子进程。父进程和子进程同时执行,允许并行任务执行。父进程等待子进程完成以避免创建僵尸进程。

3. 线程

PHP 的线程功能可通过 pthreads 等扩展来使用。线程比进程轻,并且共享相同的内存空间,因此适合需要共享数据的任务。

if (!class_exists('Thread')) {
    die("Threads are not supported in this PHP build\n");
}

echo "\nThreading Example:\n";
class MyThread extends Thread {
    public function run() {
        for ($i = 0; $i start();
$thread->join();

此示例定义了一个扩展 Thread 的 MyThread 类。 run方法在一个新线程中执行,与主线程并发运行。此方法对于 I/O 密集型操作非常有用,其中线程可以处理等待资源。

4. 发电机

生成器提供了一种实现简单协同例程的方法,允许函数迭代地产生结果,而不会阻塞整个程序。

echo "\nGenerators Example:\n";
function simpleGenerator() {
    yield 'First';
    yield 'Second';
    yield 'Third';
}

$gen = simpleGenerator();
foreach ($gen as $value) {
    echo "Generator Yielded: $value\n";
}

生成器使用yield关键字一次生成一个值,允许暂停和恢复函数,从而促进一种协作多任务处理的形式。

PHP 从同步根源到支持各种形式的并发和并行性已经取得了很大的进步。虽然同步代码对于许多用例来说仍然简单有效,但分叉进程、线程和使用生成器等技术为有效处理复杂、可并行的任务开辟了新的可能性。

版本声明 本文转载于:https://dev.to/francescoagati/concurrency-and-parallelism-in-php-6fc?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 如何使用FormData()处理多个文件上传?
    如何使用FormData()处理多个文件上传?
    )处理多个文件输入时,通常需要处理多个文件上传时,通常是必要的。 The fd.append("fileToUpload[]", files[x]); method can be used for this purpose, allowing you to send multi...
    编程 发布于2025-04-20
  • 如何使用不同数量列的联合数据库表?
    如何使用不同数量列的联合数据库表?
    合并列数不同的表 当尝试合并列数不同的数据库表时,可能会遇到挑战。一种直接的方法是在列数较少的表中,为缺失的列追加空值。 例如,考虑两个表,表 A 和表 B,其中表 A 的列数多于表 B。为了合并这些表,同时处理表 B 中缺失的列,请按照以下步骤操作: 确定表 B 中缺失的列,并将它们添加到表的末...
    编程 发布于2025-04-20
  • Go语言垃圾回收如何处理切片内存?
    Go语言垃圾回收如何处理切片内存?
    在Go Slices中的垃圾收集:详细的分析在GO中,Slice是一个动态数组,引用了基础阵列。使用切片时,了解垃圾收集行为至关重要,以避免潜在的内存泄漏。考虑使用slice使用slice的以下实现:字符串{ R:=(*Q)[0] *q =(*q)[1:len(*q)] 返回...
    编程 发布于2025-04-20
  • 如何干净地删除匿名JavaScript事件处理程序?
    如何干净地删除匿名JavaScript事件处理程序?
    删除匿名事件侦听器将匿名事件侦听器添加到元素中会提供灵活性和简单性,但是当要删除它们时,可以构成挑战,而无需替换元素本身就可以替换一个问题。 element? element.addeventlistener(event,function(){/在这里工作/},false); 要解决此问题,请考虑...
    编程 发布于2025-04-20
  • 如何从PHP中的数组中提取随机元素?
    如何从PHP中的数组中提取随机元素?
    从阵列中的随机选择,可以轻松从数组中获取随机项目。考虑以下数组:; 从此数组中检索一个随机项目,利用array_rand( array_rand()函数从数组返回一个随机键。通过将$项目数组索引使用此键,我们可以从数组中访问一个随机元素。这种方法为选择随机项目提供了一种直接且可靠的方法。
    编程 发布于2025-04-20
  • 在所有浏览器中实现左对齐文本的斜线方法
    在所有浏览器中实现左对齐文本的斜线方法
    ] 在倾斜行上的文本对齐背景在倾斜行上实现左对齐的文本可能会构成挑战,在nectera时尤其是挑战。兼容性(返回IE9)。通过引入一系列平方元素并计算其尺寸,我们可以创建一个有效的解决方案: .loop(@i) when (@i > 0){ .loop((@i - 1...
    编程 发布于2025-04-20
  • 在UTF8 MySQL表中正确将Latin1字符转换为UTF8的方法
    在UTF8 MySQL表中正确将Latin1字符转换为UTF8的方法
    在UTF8表中将latin1字符转换为utf8 ,您遇到了一个问题,其中含义的字符(例如,“jáuòiñe”)在utf8 table tabled tablesset中被extect(例如,“致电。为了解决此问题,您正在尝试使用“ mb_convert_encoding”和“ iconv”转换受...
    编程 发布于2025-04-20
  • 您如何在Laravel Blade模板中定义变量?
    您如何在Laravel Blade模板中定义变量?
    在Laravel Blade模板中使用Elegance 在blade模板中如何分配变量对于存储以后使用的数据至关重要。在使用“ {{}}”分配变量的同时,它可能并不总是最优雅的解决方案。幸运的是,Blade通过@php Directive提供了更优雅的方法: $ old_section =“...
    编程 发布于2025-04-20
  • 为什么我会收到MySQL错误#1089:错误的前缀密钥?
    为什么我会收到MySQL错误#1089:错误的前缀密钥?
    mySQL错误#1089:错误的前缀键错误descript [#1089-不正确的前缀键在尝试在表中创建一个prefix键时会出现。前缀键旨在索引字符串列的特定前缀长度长度,可以更快地搜索这些前缀。了解prefix keys `这将在整个Movie_ID列上创建标准主键。主密钥对于唯一识别...
    编程 发布于2025-04-20
  • 在Java中使用for-to-loop和迭代器进行收集遍历之间是否存在性能差异?
    在Java中使用for-to-loop和迭代器进行收集遍历之间是否存在性能差异?
    For Each Loop vs. Iterator: Efficiency in Collection TraversalIntroductionWhen traversing a collection in Java, the choice arises between using a for-...
    编程 发布于2025-04-20
  • 在细胞编辑后,如何维护自定义的JTable细胞渲染?
    在细胞编辑后,如何维护自定义的JTable细胞渲染?
    在JTable中维护jtable单元格渲染后,在JTable中,在JTable中实现自定义单元格渲染和编辑功能可以增强用户体验。但是,至关重要的是要确保即使在编辑操作后也保留所需的格式。在设置用于格式化“价格”列的“价格”列,用户遇到的数字格式丢失的“价格”列的“价格”之后,问题在设置自定义单元格...
    编程 发布于2025-04-20
  • 为什么尽管有效代码,为什么在PHP中捕获输入?
    为什么尽管有效代码,为什么在PHP中捕获输入?
    在php ;?>" method="post">The intention is to capture the input from the text box and display it when the submit button is clicked.但是,输出...
    编程 发布于2025-04-20
  • 在JavaScript中如何并发运行异步操作并正确处理错误?
    在JavaScript中如何并发运行异步操作并正确处理错误?
    同意操作execution 在执行asynchronous操作时,相关的代码段落会遇到一个问题,当执行asynchronous操作:此实现在启动下一个操作之前依次等待每个操作的完成。要启用并发执行,需要进行修改的方法。 第一个解决方案试图通过获得每个操作的承诺来解决此问题,然后单独等待它们: co...
    编程 发布于2025-04-20
  • 图片在Chrome中为何仍有边框?`border: none;`无效解决方案
    图片在Chrome中为何仍有边框?`border: none;`无效解决方案
    在chrome 在使用Chrome and IE9中的图像时遇到的一个频繁的问题是围绕图像的持续薄薄边框,尽管指定了图像,尽管指定了;和“边境:无;”在CSS中。要解决此问题,请考虑以下方法: Chrome具有忽略“ border:none; none;”的已知错误,风格。要解决此问题,请使用以下...
    编程 发布于2025-04-20
  • 为什么不````''{margin:0; }`始终删除CSS中的最高边距?
    为什么不````''{margin:0; }`始终删除CSS中的最高边距?
    在CSS 问题:不正确的代码: 全球范围将所有余量重置为零,如提供的代码所建议的,可能会导致意外的副作用。解决特定的保证金问题是更建议的。 例如,在提供的示例中,将以下代码添加到CSS中,将解决余量问题: body H1 { 保证金顶:-40px; } 此方法更精确,避免了由全局保证金重置引...
    编程 发布于2025-04-20

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3