PHP 多进程怎么用
平时写PHP代码,很多时候我们写的都是单进程脚本——比如处理一个表单提交、拉取一条数据,执行完就结束。但如果要同时干好几件事,比如同时给10个用户发通知、批量生成100张图片缩略图,单进程就会慢得像蜗牛,这时候就得用到PHP的多进程了。简单说,多进程就是让PHP同时“分身”干几件事,充分利用电脑的性能,效率直接翻倍。不过很多人觉得多进程太复杂,其实用起来一点不难,咱们一步步说。
什么是PHP多进程?

先讲个生活化的例子:你自己一个人(单进程)做饭,要先洗米、再炒菜、最后盛饭,得按顺序做,花20分钟;如果叫上1个朋友(相当于启动1个子进程),你们分工——你洗米炒菜,朋友盛饭,只需要10分钟。PHP的多进程就是这么回事:主进程是你,子进程是你朋友,系统帮你管着这些“分身”,让它们同时干活,互不干扰。
PHP实现多进程,主要靠pcntl扩展,这个扩展不是默认开启的,得先确认你的PHP环境有没有装。可以在终端敲php -m,看看列表里有没有pcntl,没有的话得重新编译PHP,加上--enable-pcntl参数,或者用类似yum install php-pcntl的命令装扩展,这个步骤只要跟着教程来,基本不会出错。
多进程怎么用?手把手教你写
接下来咱们写个简单的例子,同时输出1到5的数字,单进程要5秒,多进程只需要2秒,对比一下就懂了。
首先是单进程的写法,用sleep模拟耗时操作:
for ($i = 1; $i <= 5; $i++) {
sleep(1);
echo "单进程输出:$i\n";
}
这个很简单,循环5次每次等1秒,总共5秒,没啥好说的。
然后是多进程的写法,核心函数是pcntl_fork()——这个函数会“分叉”出一个子进程,返回值不一样:父进程(主进程)拿到的是子进程的ID,子进程拿到的是0,靠这个就能区分父子进程了。
$childPids = []; // 存子进程ID,后面要收摊子
for ($i = 1; $i <= 5; $i++) {
$pid = pcntl_fork();
if ($pid == -1) {
// 分叉失败,抛出错误
die("创建子进程失败");
} elseif ($pid == 0) {
// 子进程逻辑
sleep(1);
echo "子进程输出:$i\n";
exit(); // 子进程干完活必须退出,不然会和父进程一起循环
} else {
// 父进程把子进程ID存起来,后面要等它结束
$childPids[] = $pid;
}
}
// 收摊子:等所有子进程结束,避免变成“僵尸进程”
foreach ($childPids as $pid) {
pcntl_waitpid($pid, $status);
}
这个代码跑起来大概只花2秒,因为5个子进程是同时sleep的,不是按顺序等。这里要注意两个坑:第一,子进程必须加exit,不然会重复执行父进程的循环;第二,必须用pcntl_waitpid收进程,不然子进程结束后会变成僵尸进程,占着系统资源,时间长了会拖慢服务器。
多进程的实际用法
光会写例子没用,得落地到实际场景。比如给100个用户发营销短信,单进程要循环100次,每次发1秒,总耗时100秒;用多进程,开5个子进程,每个负责20个用户,总耗时就变成20秒,效率提升5倍。还有批量处理图片、拉取多个API接口数据,这些需要并行处理的任务,多进程都能帮上忙。
最后提醒两个注意点:第一,子进程之间是独立的,不能直接共用变量,要传参的话得用临时文件、消息队列或者共享内存;第二,不要开太多子进程,比如开20个就比开5个慢,因为系统要花时间调度这些进程,一般开的数量和电脑的CPU核心数差不多就好,避免资源浪费。