首先我们要知道创建守护进程的五个步骤:
- 创建子进程,终止父进程
- 在子进程中创建新会话
- 改变工作目录(默认继承了父进程的当前工作目录)
- 重设文件创建掩码(默认继承了父进程的文件创建掩码)
- 关闭文件描述符(默认继承了父进程打开了的文件)
还要安装有pcntl扩展,可通过php -m查看是否安装
然后直接上代码
<?php
function daemon() {
// fork一个子进程
$pid = pcntl_fork();
//判断$pid
switch ($pid) {
case -1:
die('fork失败');
break;
case 0:
// 这里是子进程执行的代码
// 创建新会话
if ( ($sid = posix_setsid()) <= 0 ) {
die("创建失败\n");
}
// 3.改变工作目录
if (chdir('/') === false) {
die("改变工作目录失败\n");
}
// 4.重设文件创建掩码
umask(0);
// 5.关闭文件描述符
fclose(STDIN);
fclose(STDOUT);
fclose(STDERR);
break;
default:
// 这里是父进程执行的代码 直接退出即可
exit;
break;
}
}
//fork子进程
function fork() {
global $childs;
//fork子进程
$pid = pcntl_fork();
switch ($pid) {
case -1:
die('fork失败');
break;
case 0:
// 这里是子进程执行的代码
while (true) {
sleep(5);
}
break;
default:
// 这里是父进程执行的代码 ,将fork的子进程id 放入全局变量$childs中
$childs[$pid] = $pid;
break;
}
}
//创建守护进程
daemon();
//定义全局变量
$childs = [];
//需要fork的子进程数,这里创建3个子进程
$count = 3;
//循环创建子进程
for ($i = 0; $i < $count; $i++) {
fork();
}
//这里判断 当子进程的数量大于0 的时候 等待子进程的退出,并重新fork新的子进程
while ( count($childs) ) {
if ( ($exit_id = pcntl_wait($status)) > 0 ) {
unset($childs[$exit_id]);
}
if ( count($childs) < 3 ) {
fork();
}
}
需要注意的是守护进程不能有输出
需要注意的是守护进程不能有输出
需要注意的是守护进程不能有输出
至此,一个简单的守护进程就创建好了,还有三个子进程,每当子进程出现问题退出后,都会重新创建一个子进程来代替
可以结合控制信号,给脚本start|stop|reload
等参数来实现更加便捷化的操作
是不是很简单