This article mainly introduces the two daemon methods in php. Interested friends can refer to it. I hope it can help everyone.
The first way is to use nohup and & together.
Adding the ampersand after the command allows the started process to run in the background without occupying the console. The console can also run other commands. Here I use a while infinite loop to demonstrate. The code is as follows
<?php while(true){ echo time().PHP_EOL; sleep(3); }
Use & method to start the process
[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]#
You can see that the process does not occupy the console, and the console can also run other commands. At this time We can also use the fg command to restore the process to the normal mode of occupying the console.
##
[root@localhost php]# fg php deadloop.php 1470996682 1470996685 1470996688 1470996691
The above is a brief introduction to the & command
SIGHUP会在以下3种情况下被发送给相应的进程: 1、终端关闭时,该信号被发送到session首进程以及作为job提交的进程(即用 & 符号提交的进 程) 2、session首进程退出时,该信号被发送到该session中的前台进程组中的每一个进程 3、若父进程退出导致进程组成为孤儿进程组,且该进程组中有进程处于停止状态(收到SIGSTOP或 SIGTSTP信号),该信号会被发送到该进程组中的每一个进程。
Combining 1 and 2 we know that regardless of whether the process is started with & (job mode), the SIGHUP signal will be received when closing the terminal. So how will the process handle the SIGHUP signal? Look at the sentence also taken from Baidu Encyclopedia
系统对SIGHUP信号的默认处理是终止收到该信号的进程。所以若程序中没有捕捉该信号,当收到该 信号时,进程就会退出。
<?php pcntl_signal(SIGHUP, function(){ //这地方处理信号的方式我们只是简单的写入一句日志到文件中 file_put_contents('logs.txt', 'pid : ' . posix_getpid() . ' receive SIGHUP 信号' . PHP_EOL); }); while(1) { sleep(10); pcntl_signal_dispatch(); }
[root@localhost php]# ps -ef | grep deadloop.php root 16112 1 0 17:20 ? 00:00:00 php deadloop.php root 16138 16115 0 17:24 pts/4 00:00:00 grep deadloop.php [root@localhost php]# cat logs.txt pid : 16112 receive SIGHUP 信号
[root@localhost php]# nohup php deadloop.php nohup: 忽略输入并把输出追加到"nohup.out"
[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
At this time, close the terminal, the process will not end, but become an orphan process (ppid=1 ) because the parent process that created it exited.
##
[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 ~]#
Conclusion : So when we combine the nohup and & methods, the started process will not occupy the console nor rely on the console. After the console is closed, the process will be adopted by process No. 1 and become an orphan process. This is the same as the daemon process mechanism. Very similar.
[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]#
The above is an introduction to the first implementation method.
The second implementation method is to implement it through code according to the rules and characteristics of the daemon process. The biggest feature of the daemon process is that it is separated from the user terminal and session. The following is the implemented code, with comments in key places.
<?php $pid = pcntl_fork(); if ($pid == -1) { throw new Exception('fork子进程失败'); } elseif ($pid > 0) { //父进程退出,子进程不是进程组长,以便接下来顺利创建新会话 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); }
Related recommendations:
The above is the detailed content of Two methods of daemon process in php. For more information, please follow other related articles on the PHP Chinese website!