Process vs PCNTL
我们知道,通过 PHP 自带的扩展 PCNTL 可以实现基于 Unix 的多进程管理(不能用于 Web 服务器环境),比如 Laravel 自带的队列系列解决方案Horizon 就会用到这个扩展,但是 PCNTL 有很多坑,比如:
fork
因此,从 1.7.2 版本开始,Swoole 内置了一个进程管理模块 Process 来替代 PHP 自带的 PCNTL 扩展,和 PCNTL 一样, Process 模块也只能在命令行使用,但提供了比 PCNTL 扩展更强大的功能,更容易上手的 API,使 PHP 在多进程编程方面更加轻松。 Process 模块主要提供了以下特性:
支持基于 Unix Socket 和 sysvmsg 消息队列的进程间通信,只需调用 write / read 或者 push / pop 即可;
支持重定向标准输入和输出,在子进程内 echo 不会打印到屏幕,而是写入管道,读键盘输入时可以重定向为管道读取数据;
配合 Event 模块,创建的 PHP 子进程支持异步事件驱动模式;
提供了 exec 接口,创建的进程可以执行其他程序,与原 PHP 父进程之间可以方便的通信。
下面我们就来看看如果通过 Swoole 的 Process 模块在 PHP 中实现多进程管理,同时演示上上述特性的实现。
多进程 TCP 服务器实现
我们以一个模拟 TCP 服务器为例,演示基于 Swoole 的多进程 服务器 实现,在这段代码中,主进程启动后,会启动多个子进程(具体支持的子进程数通过参数设置),处理客户端连接和请求消息,子进程退出后,主进程会重新创建新的子进程,如果主进程退出,则子进程在处理完当前请求后,也会退出。
对应的 TCP 服务器实现代码如下:
namespace Swoole;
class TcpServer
{
// 系统支持的最大子进程数
const MAX_PROCESS = 3;
// 子进程pid数组
private $pids = [];
// 网络套接字
private $socket;
// 主进程 ID
private $mpid;
/**
* 服务器主进程业务逻辑
*/
public function run()
{
// 主进程
$process