php实现多进程
PHP 实现多进程的方法
PHP 可以通过多种方式实现多进程处理,以下是几种常见的方法:
使用 pcntl 扩展
pcntl(Process Control)是 PHP 的多进程扩展,适用于 Unix/Linux 系统。以下是一个简单的多进程示例:
<?php
$pid = pcntl_fork();
if ($pid == -1) {
die('Could not fork');
} elseif ($pid) {
// 父进程
pcntl_wait($status); // 等待子进程结束
} else {
// 子进程
echo "Child process\n";
exit(0);
}
?>
使用 exec 或 shell_exec
通过调用外部命令或脚本实现多进程:
<?php
exec('php worker.php > /dev/null &');
?>
使用 Gearman
Gearman 是一个分布式任务分发系统,可以用于多进程任务处理:
<?php
$client = new GearmanClient();
$client->addServer();
$client->doBackground('worker_function', 'data');
?>
使用消息队列
结合消息队列(如 RabbitMQ、Redis)实现多进程任务分发:
<?php
$queue = new Redis();
$queue->connect('127.0.0.1');
$queue->rPush('task_queue', json_encode(['task' => 'data']));
?>
注意事项
- Windows 系统不支持 pcntl 扩展,需使用其他方法(如 exec)。
- 多进程可能导致资源竞争,需使用锁机制(如 flock)或共享内存(shmop)。
- 子进程会继承父进程的资源,需注意内存泄漏问题。
多进程通信
多进程间可以通过以下方式通信:
- 管道(pipe)
- 共享内存(shmop)
- 消息队列(msg_* 函数)
- 信号(signal)
<?php
$shm_id = shmop_open(1234, 'c', 0644, 1024);
shmop_write($shm_id, 'data', 0);
?>
进程池实现
通过 fork 多个子进程并管理其生命周期:
<?php
$workers = [];
$worker_num = 5;
for ($i = 0; $i < $worker_num; $i++) {
$pid = pcntl_fork();
if ($pid == -1) {
die('fork error');
} elseif ($pid) {
$workers[] = $pid;
} else {
// 子进程工作代码
exit(0);
}
}
// 父进程等待所有子进程结束
foreach ($workers as $pid) {
pcntl_waitpid($pid, $status);
}
?>
多进程与性能
- 多进程适合 CPU 密集型任务
- I/O 密集型任务建议结合异步 I/O(如 Swoole)
- 进程数不宜过多,通常为 CPU 核心数的 1-2 倍
替代方案
对于高并发场景,可考虑:
- Swoole 扩展(协程+多进程)
- ReactPHP 事件循环
- OpenSWOOLE 框架
<?php
$server = new Swoole\Server('127.0.0.1', 9501);
$server->set([
'worker_num' => 4,
]);
$server->on('receive', function ($serv, $fd, $reactor_id, $data) {
$serv->send($fd, "Response: $data");
});
$server->start();
?>






