PHP中的并发与多线程:从理论到实践

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

PHP中的并发与多线程:现代方法



PHP传统上与同步代码执行相关联。然而,现代Web应用程序需要同时处理多个任务:从文件上传到大数据解析。在本文中,我们将探讨如何使用内置和第三方工具在PHP中实现并发与多线程。



什么是并发与多线程?



并发是指程序通过任务切换"同时"执行多个任务的能力。多线程是并发的一种特殊情况,任务在操作系统的独立线程中执行。



在PHP 7.4之前,没有对线程的原生支持。但随着pthreads和parallel扩展的出现,以及进程处理能力的改进,情况发生了变化。



1. 使用parallel扩展实现多线程



parallel扩展是PHP 7.4+中处理线程的现代方式。它使用共享内存,允许在线程之间高效地交换数据。



安装:

pecl install parallel


创建线程示例:

<?phpuse parallel\\Runtime;

$runtime = new Runtime();$future = $runtime->run(function() { // 繁重的计算 $result = 0; for ($i = 0; $i < 1000000; $i++) { $result += sqrt($i); } return $result;});

echo "主线程继续工作...";$result = $future->value(); // 获取结果echo "结果: $result";?>


parallel的优势:

  • 原生线程支持,无需额外依赖
  • 线程间共享内存
  • 支持传递闭包和对象


缺点:

  • 需要PHP 7.4+和ZTS(Zend线程安全)
  • 不支持Windows
  • 调试困难


2. 通过进程实现异步:pcntl_fork



如果不需要共享内存,可以使用pcntl_fork()处理进程。这是经典的Unix方法。



<?php$pid = pcntl_fork();

if ($pid == -1) { die("进程创建失败");} elseif ($pid) { // 父进程 echo "父进程:等待子进程..."; pcntl_wait($status); echo "父进程:子进程已完成";} else { // 子进程 echo "子进程:执行任务..."; sleep(3); exit(0);}?>


进程处理的特性:

  • 每个进程拥有独立的内存
  • 使用套接字、共享内存(shmop)或文件进行数据交换
  • 需要通过pcntl_wait()处理僵尸进程


3. 通过异步函数和ReactPHP实现并发



对于I/O任务(网络请求、文件读取),使用ReactPHP或Amp等异步库更高效。它们不创建线程,但通过事件循环实现并发执行。



ReactPHP示例:

<?phprequire 'vendor/autoload.php';

use React\\EventLoop\\Factory;use React\\Http\\Browser;

$loop = Factory::create();$client = new Browser($loop);

$promises = [];$urls = [ 'https://api.example.com/data1', 'https://api.example.com/data2', 'https://api.example.com/data3'];

foreach ($urls as $url) { $promises[] = $client->get($url);}

// 并行等待所有请求$results = [];foreach ($promises as $promise) { $results[] = $promise->wait();}

$loop->run();print_r($results);?>

博客

书籍推荐