nginx的信号处理,根据传入的信号做处理。
如终止掉进程
如热处理等都可以通过信号处理器实现
信号(signal)的名字都以SIG开头,查看全部信号名称
kill[参数][进程号],发送指定的信号到相应进程。不指定型号将发送SIGTERM(15)终止指定进程。
常用信号:
SIGTERM(15),
SIGINT(2) 快速关闭 <同 Ctrl + C>
SIGQUIT(3) 从容关闭 等待进程任务执行完毕
SIGHUP(1)重载配置 用新的配置开始新的工作进程 从容关闭旧的工作进程
SIGKILL(9) 强制终止
我们以kill SIGTERM(15), Ctrl + C SIGINT(2)为例,其他信号以此类推< kill 信号数字 进程PID >或< Kill -QUIT 进程PID>就可以:
class Server{
private $_mainSocket;
private $_newSocket;
private $_EventBase;
public $pids;
public function __construct()
{
$this->forkServer();
file_put_contents('/tmp/master.pid',getmypid()); //
}
public function signalHandler($signo){
switch ($signo) {
case SIGTERM:
echo 'kill了进程 pid:'.getmypid().PHP_EOL;
//如果是子进程 重新fork一个子进程 实现热处理
exit;
break;
case SIGINT:
echo '执行的是 ctrl+c pid:'.getmypid().PHP_EOL;
exit;
break;
default:
// 处理所有其他信号
}
}
protected function monitor(){
//注册信号处理器,信号信号触发时,执行的闭包(进程关闭之后,回收主进程的pid文件)
pcntl_signal(SIGINT,[$this,'signalHandler']);
pcntl_signal(SIGTERM,[$this,'signalHandler']);
while (1){
pcntl_signal_dispatch(); //挂起状态 有信号时才会触发 并不会造成死循环
//调用等待信号的处理器,触发信号事件,挂起状态
$pid=pcntl_wait($status,WUNTRACED); //等待子进程中断,防止子进程成为僵尸进程。
$status=0;
}
}
public function forkServer($count=2){
for ($i = 0; $i < $count; ++$i)
{
$pid = pcntl_fork();
if ($pid < 0) {
exit('生成子进程失败\n');
} else if ($pid > 0) {
// 父进程
$this->pids[] = $pid;
} else {
$this->monitor(); //监视子进程的信号
$this->listen();
exit;
}
}
$this->monitor(); //监视主进程的信号
}
public function listen(){...}
}
$server=new Server();
启动
重新打开一个shell窗口查看进程
kill一个子进程
打印信息
ctrl + c退出
有关设置进程名称
如退出nginx的命令 Kill -QUIT nginx
这里nginx即nginx主进程的名称 对应主进程的pid
上边我们没做这一部分,在此补充。