이 글에서는 주로 PHP 데몬의 두 가지 구현 방법을 소개하며, 구체적인 예를 바탕으로 PHP 데몬의 원리와 관련 구현 방법, 동작 주의사항을 분석합니다. 도움이 필요한 친구들은 참고할 수 있습니다
자세한 내용은 다음과 같습니다.
첫 번째 방법은 nohup과 &를 함께 사용하는 것입니다.
명령 뒤에 앰퍼샌드를 추가하면 콘솔을 차지하지 않고 백그라운드에서 실행할 수 있습니다. 여기서는 while 무한 루프를 사용하여 보여줍니다.
<?php while(true){ echo time().PHP_EOL; sleep(3); }
[root@localhost php]# php deadloop.php & [1] 3454 [root@localhost php]# ps aux | grep 3454 root 3454 0.0 0.8 284544 8452 pts/0 T 18:06 0:00 php deadloop.php root 3456 0.0 0.0 103316 896 pts/0 S+ 18:08 0:00 grep 3454 [1]+ Stopped php deadloop.php [root@localhost php]#
[root@localhost php]# fg php deadloop.php 1470996682 1470996685 1470996688 1470996691
SIGHUP은 다음 3가지 상황에서 해당 프로세스로 전송됩니다.
1. 세션 첫 번째 프로세스 그리고 작업으로 제출된 프로세스(즉, & 기호와 함께 제출된 프로세스) 2. 세션의 첫 번째 프로세스가 종료되면 해당 세션의 포그라운드 프로세스 그룹에 있는 모든 프로세스에 신호가 전송됩니다.
3. 상위 프로세스가 종료되면 프로세스 그룹이 고아 프로세스 그룹이고 프로세스 그룹의 프로세스가 중지되면(SIGSTOP 또는 SIGTSTP 신호가 수신됨) 프로세스 그룹의 모든 프로세스에 신호가 전송됩니다.
1과 2를 결합하면 프로세스가 &(작업 모드)에서 시작되었는지 여부에 관계없이 터미널을 닫을 때 SIGHUP 신호가 수신된다는 것을 알 수 있습니다. 그러면 프로세스가 SIGHUP 신호를 수신하면 어떻게 될까요? Baidu Encyclopedia에서 가져온 동일한 문장을 참조하세요.
<?php declare(ticks = 1); pcntl_signal(SIGHUP, function(){ // 这地方处理信号的方式我们只是简单的写入一句日志到文件中 file_put_contents('logs.txt', 'pid : ' . posix_getpid() . ' receive SIGHUP 信号' . PHP_EOL); }); while(true){ echo time().PHP_EOL; sleep(3); }
[root@localhost php]# nohup php deadloop.php
[root@localhost php]# ls cmd.sh deadloop.php getPhoto.php nohup.out pics [root@localhost php]# tail -f nohup.out 1470999772 1470999775 1470999778 1470999781 1470999784 1470999787 1470999790 1470999793 1470999796 1470999799 1470999802
[root@localhost ~]# ps -ef | grep 3554 root 3554 3497 0 19:09 pts/0 00:00:00 php deadloop.php root 3575 3557 0 19:10 pts/1 00:00:00 grep 3554 [root@localhost ~]# ps -ef | grep 3554 root 3554 1 0 19:09 ? 00:00:00 php deadloop.php root 3577 3557 0 19:10 pts/1 00:00:00 grep 3554 [root@localhost ~]#
결론:
nohup과 & 메소드를 결합하면 시작된 프로세스는 콘솔을 차지하지 않고 콘솔에 의존하지 않으며 콘솔이 닫힌 후에는 프로세스가 No로 채택됩니다. . 1이며 데몬 프로세스의 메커니즘과 매우 유사한 Orphan 프로세스가 됩니다.[root@localhost php]# nohup php deadloop.php >logs.txt 2>error.txt & [1] 3612 [root@localhost php]# ps -ef |grep 3612 root 3612 3557 0 19:18 pts/1 00:00:00 php deadloop.php root 3617 3557 0 19:19 pts/1 00:00:00 grep 3612 [root@localhost php]#
. 데몬 프로세스의 가장 큰 특징은 사용자 단말과 세션이 분리되어 있다는 점입니다. 구현된 코드(주요 위치에 주석 포함) <?php
$pid = pcntl_fork();
if ($pid == -1)
{
throw new Exception('fork子进程失败');
}
elseif ($pid > 0)
{
//父进程退出,子进程变成孤儿进程被1号进程收养,进程脱离终端
exit(0);
}
// 最重要的一步,让该进程脱离之前的会话,终端,进程组的控制
posix_setsid();
// 修改当前进程的工作目录,由于子进程会继承父进程的工作目录,修改工作目录以释放对父进程工作目录的占用。
chdir('/');
/*
* 通过上一步,我们创建了一个新的会话组长,进程组长,且脱离了终端,但是会话组长可以申请重新打开一个终端,为了避免
* 这种情况,我们再次创建一个子进程,并退出当前进程,这样运行的进程就不再是会话组长。
*/
$pid = pcntl_fork();
if ($pid == -1)
{
throw new Exception('fork子进程失败');
}
elseif ($pid > 0)
{
// 再一次退出父进程,子进程成为最终的守护进程
exit(0);
}
// 由于守护进程用不到标准输入输出,关闭标准输入,输出,错误输出描述符
fclose(STDIN);
fclose(STDOUT);
fclose(STDERR);
/*
* 处理业务代码
*/
while(TRUE)
{
file_put_contents('log.txt', time().PHP_EOL, FILE_APPEND);
sleep(5);
}
관련 권장 사항:
PHP 데몬화 구현 방법위 내용은 PHP 데몬의 두 가지 방법에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!