🚀 PHP 多執行緒與非阻塞實戰:從「循序執行」到「高併發協程」
💡 前言:打破 PHP 「慢」與「卡」的刻板印象
當開發者面對大量郵件發送、圖片轉檔或複雜 API 呼叫時,常會感嘆 PHP 的同步阻塞特性。但事實上,透過多執行緒、協程或事件循環,我們完全能讓 PHP 展現不輸 Go 或 Node.js 的平行處理能力。
一、 技術決策矩陣:我該選哪一種? (Decision Matrix)
在實作之前,請依照您的場景選擇對應的技術棧:
| 方案 | 核心技術 | 適用場景 | 優點 | 缺點 |
| Swoole | 協程 (Coroutine) | 高併發 API、I/O 密集型 | 極致效能、支援 PHP 8 | 需安裝 C 擴充、學習曲線較陡 |
| ReactPHP | 事件循環 (Event Loop) | 輕量非阻塞任務、WebSocket | 純 PHP、免 ZTS 環境 | CPU 密集型任務表現一般 |
| pthreads | 多執行緒 (Thread) | CPU 密集型運算、CLI 任務 | 真正並行、共享記憶體 | 需 ZTS 版本、PHP 8 支援度有限 |
| pcntl | 多進程 (Process) | 簡單 CLI 背景任務 | 穩定、原生支援 | 資源消耗大、進程通訊複雜 |
二、 四大方案實戰範例 (Practical Implementation)
1. Swoole:現代化協程的王者 (推薦)
Swoole 的協程就像是「輕量級執行緒」,它在 I/O 等待時會自動切換,不佔用 CPU 資源。
PHP
<?php
use Swoole\Coroutine;
use function Swoole\Coroutine\run;
// 協程入口
run(function () {
$results = [];
for ($i = 0; $i < 5; $i++) {
// 建立協程,並行執行任務
Coroutine::create(function () use ($i, &$results) {
// 模擬非阻塞 I/O (如 API 請求)
Coroutine::sleep(rand(1, 2));
echo "✅ 任務 {$i} 完成\n";
$results[] = "Data_{$i}";
});
}
echo "🚀 主程式繼續執行,不被阻塞...\n";
});
2. ReactPHP:免擴充的非阻塞優雅
基於事件驅動,適合不想變動 PHP 環境設定的專案。
PHP
<?php
require 'vendor/autoload.php';
$loop = React\EventLoop\Loop::get();
for ($i = 0; $i < 5; $i++) {
// 註冊非阻塞計時器
$loop->addTimer($i + 1, function () use ($i) {
echo "⏰ 定時任務 {$i} 在秒數後觸發\n";
});
}
echo "🔥 事件循環已啟動...\n";
$loop->run();
3. pthreads:利用多核心處理複雜運算
如果您需要處理的是數學運算或加解密,pthreads 能讓多個核心同時運作。
PHP
<?php
class Calculator extends Thread {
private $val;
public function __construct($val) { $this->val = $val; }
public function run() {
// 模擬 CPU 密集運算
$result = $this->val * $this->val;
echo "🧮 運算結果: {$result}\n";
}
}
$work = [];
for ($i = 1; $i <= 5; $i++) {
$work[$i] = new Calculator($i);
$work[$i]->start(); // 啟動真執行緒
}
foreach ($work as $t) { $t->join(); } // 等待回收
4. pcntl_fork:老派但極致穩定的進程隔離
適合在 Linux CLI 環境下進行簡單的背景分流。
PHP
<?php
$pid = pcntl_fork();
if ($pid == -1) {
exit("無法建立進程");
} elseif ($pid) {
// 父進程邏輯
echo "👨👦 父進程正在監控子進程 (PID: $pid)...\n";
pcntl_wait($status); // 等待子進程結束
echo "🏁 所有任務完成\n";
} else {
// 子進程邏輯
echo "👶 子進程開始處理耗時轉檔...\n";
sleep(3);
exit(0); // 務必退出,避免子進程繼續跑主程式
}
三、 PHP vs. Python:異步機制深度解碼 (Flowchart)
在處理機制上,Python 的 asyncio 較接近 ReactPHP 的單線程事件循環;而 Swoole 則更進一步,結合了多進程模型與協程,這使得 PHP 在處理極大規模併發時,往往能比 Python 展現出更高的吞吐量。
四、 結論:架構師的務實心法 (Conclusion)
優化 PHP 效能時,請遵循以下步驟:
優先考慮非同步化:先檢查是否能改用 Redis Queue (Laravel Queue) 非同步處理,這是最穩定的作法。
I/O 瓶頸選 Swoole:如果需要即時響應且併發量大,Swoole 是目前的工業標準。
單一任務優化選 ReactPHP:不需要額外 C 擴充,適合處理簡單的第三方 API 串接。
沒有留言:
張貼留言