画江湖之 PHP 多进程开发 [实现守护进程化]
特点
- 后台运行
- 不受任何终端控制
- 可以由 系统启动脚本/etc/rc.local 、crontab任务、用户shell 三种方式执行
主要实现的核心过程
如何守护进程化
1.创建子进程,终止父进程
2.在子进程中创建新会话
3.改变工作目录(默认继承了父进程的当前工作目录)
4.重设文件创建掩码(默认继承了父进程的文件创建掩码)
5.关闭文件描述符(默认继承了父进程打开了的文件)
主要的函数
1.pcntl_fork, exit 创建子进程,退出进程
2.posix_setsid 让当前进程变为主会话
3.chdir('/') 当前工作目录改为 root 目录
4.umask(0) 改变当前的 umask 为最宽松掩码
5.fclose 关闭一个已打开的文件指针
代码段
<?php
function daemon() {
// 1-1
$pid = pcntl_fork();//fork一个子进程
switch ($pid) {
case -1:
die('Create failed');
break;
case 0:
// Child
// 2.
if ( ($sid = posix_setsid()) <= 0 ) {//让当前的子进程变成住会话
die("Set sid failed.\n");
}
// 3.
if (chdir('/') === false) {//把当前目录变成root目录
die("Change dir failed.\n");
}
// 4.
umask(0);//重设置文件的创建掩码
// 5.
fclose(STDIN);//关闭一个打开的文件指针
fclose(STDOUT);
fclose(STDERR);
break;
default:
// Parent
// 1-2//退出主进程
exit;
break;
}
}
function fork() {
global $childs;
$pid = pcntl_fork();
switch ($pid) {
case -1:
die('Create failed');
break;
case 0:
// Child
while (true) {
sleep(5);
}
break;
default:
// Parent
$childs[$pid] = $pid;
break;
}
}
daemon();
$childs = [];
$count = 3;
for ($i = 0; $i < $count; $i++) {
fork();
}
while ( count($childs) ) {
if ( ($exit_id = pcntl_wait($status)) > 0 ) {
unset($childs[$exit_id]);
}
if ( count($childs) < 3 ) {
fork();
}
}
本作品采用《CC 协议》,转载必须注明作者和本文链接
我们现在都是 用artisan命令起一个while的程序,然后一直跑,再用定时任务执行一个shell脚本,一分钟去检测一下while还在不在,不在就把while程序拉起来
@Complicated 这种方式也可以
@Krisji 这也是没办法了,,哎
@Complicated 可以使用 supervisor 来管理那个进程