本文目录导读:

在 PHP 中实现运行时协程,主要有以下几种方式:
使用 Swoole 扩展(最常用)
<?php
// Swoole 协程示例
use Swoole\Coroutine;
// 创建协程
Coroutine::create(function () {
echo "协程1开始\n";
// 模拟IO操作
Coroutine::sleep(1);
echo "协程1结束\n";
});
Coroutine::create(function () {
echo "协程2开始\n";
Coroutine::sleep(0.5);
echo "协程2结束\n";
});
echo "主程序继续运行\n";
// 等待所有协程完成
Swoole\Coroutine\run();
?>
使用 Fiber(PHP 8.1+ 原生)
<?php
// PHP 8.1+ 原生 Fiber 示例
$fiber = new Fiber(function() {
echo "Fiber开始\n";
// 暂停执行,返回给调用者
$value = Fiber::suspend('暂停中');
echo "收到值: $value\n";
echo "Fiber结束\n";
return "Fiber返回值";
});
// 启动 Fiber
$result = $fiber->start();
echo "主程序: $result\n";
// 恢复 Fiber 执行
$result = $fiber->resume('继续执行');
echo "主程序: $result\n";
?>
并发协程管理
<?php
// 并发执行多个协程
use Swoole\Coroutine;
use Swoole\Coroutine\Channel;
$channel = new Channel(10);
// 创建多个任务
$tasks = [
'task1' => function() {
Coroutine::sleep(1);
return '任务1结果';
},
'task2' => function() {
Coroutine::sleep(0.5);
return '任务2结果';
},
'task3' => function() {
Coroutine::sleep(2);
return '任务3结果';
}
];
// 并发执行所有任务
$results = Coroutine\parallel($tasks);
print_r($results);
?>
协程池实现
<?php
class CoroutinePool {
private array $coroutines = [];
private int $maxConcurrency;
public function __construct(int $maxConcurrency) {
$this->maxConcurrency = $maxConcurrency;
}
public function submit(callable $task, ...$args): void {
$this->coroutines[] = [
'task' => $task,
'args' => $args
];
}
public function execute(): array {
$results = [];
// 分批执行
$batches = array_chunk($this->coroutines, $this->maxConcurrency);
foreach ($batches as $batch) {
foreach ($batch as $coroutine) {
$results[] = call_user_func_array($coroutine['task'], $coroutine['args']);
}
}
return $results;
}
}
// 使用示例
$pool = new CoroutinePool(3);
$pool->submit(function($data) {
usleep(100000); // 模拟IO
return "处理: $data";
}, '数据1');
$pool->submit(function($data) {
usleep(100000);
return "处理: $data";
}, '数据2');
$results = $pool->execute();
print_r($results);
?>
协程之间通信
<?php
use Swoole\Coroutine;
use Swoole\Coroutine\Channel;
$channel = new Channel();
// 生产者协程
Coroutine::create(function() use ($channel) {
for ($i = 0; $i < 5; $i++) {
echo "生产: $i\n";
$channel->push($i);
Coroutine::sleep(0.1);
}
});
// 消费者协程
Coroutine::create(function() use ($channel) {
while (true) {
$data = $channel->pop();
if ($data === false) break;
echo "消费: $data\n";
Coroutine::sleep(0.2);
}
});
Coroutine\run();
?>
实际的 HTTP 请求示例
<?php
// 使用 Swoole 实现并发 HTTP 请求
use Swoole\Coroutine\Http\Client;
use Swoole\Coroutine;
$urls = [
'https://api.example.com/user/1',
'https://api.example.com/user/2',
'https://api.example.com/user/3',
];
$requests = [];
foreach ($urls as $url) {
$requests[] = Coroutine::create(function() use ($url) {
$client = new Client('api.example.com', 443, true);
$client->get('/user/1');
return $client->body;
});
}
// 等待所有请求完成
Coroutine\run();
echo "所有请求完成\n";
?>
协程超时控制
<?php
use Swoole\Coroutine;
use Swoole\Coroutine\Channel;
function withTimeout(callable $task, float $timeout) {
$channel = new Channel(1);
// 启动任务协程
Coroutine::create(function() use ($task, $channel) {
try {
$result = $task();
$channel->push(['success' => true, 'data' => $result]);
} catch (\Exception $e) {
$channel->push(['success' => false, 'error' => $e->getMessage()]);
}
});
// 等待结果或超时
$result = $channel->pop($timeout);
if ($result === false) {
return ['success' => false, 'error' => '超时'];
}
return $result;
}
// 使用示例
$result = withTimeout(function() {
Coroutine::sleep(2);
return '任务完成';
}, 1.5);
var_dump($result);
?>
注意事项
- 协程不是线程:PHP 的协程是单线程的,不能利用多核 CPU
- 阻塞操作:避免在协程中使用阻塞操作(如 sleep、file_get_contents),应使用协程版本
- 内存管理:协程会占用内存,需要注意控制协程数量
- 异常处理:协程中的异常需要通过 try-catch 捕获
选择哪种方案取决于你的 PHP 版本和环境需求,如果是 PHP 8.1+,可以使用原生的 Fiber;如果需要更强大的功能,建议使用 Swoole 扩展。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播