This article mainly introduces two kinds of daemons in PHP, the interests of the small partners, the hope can help everyone.
The first way, with the use of Nohup and &.
With the & symbol appended to the command, you can get the started process to run in the background without occupying the console, and the console can run other commands, where I use a while dead loop to do the demo, the code is as follows
<?phpwhile (True) { echo time (). Php_eol; Sleep (3);}
Use & to start the process
[Root@localhost php]# php deadloop.php &[1] 3454[root@localhost php]# PS aux | grep 3454root 3454 0.0 0.8 284544 8452 pts/0 T 18:06 0:00 php deadloop.phproot 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, the console can also run other commands, and we can also use the FG command to get the process back to the normal occupancy console mode.
[Root@localhost php]# fgphp deadloop.php1470996682147099668514709966881470996691
The above is about the & command Brief introduction
Let's look at another command nohup
Add nohup before the command, the process started will ignore the Linux hang Signal (SIGHUP), which will trigger the Linux under the SIGHUP signal, the following excerpt from the Baidu Encyclopedia:
Sighup will be sent to the appropriate process in the following 3 cases: 1, when the terminal is closed, the signal is sent to the session first process and the process submitted as a job (that is, the process submitted with the & symbol) 2, the session first process exits, The signal is sent to each process in the foreground process group in the session 3, if the parent process exits causing the process to be composed of an orphan process group, and a process in the process group is in a stopped state (receiving a sigstop or SIGTSTP signal), the signal is sent to each process in the process group.
Combined with 1 and 2 we know that regardless of whether the process started in & (Job), the terminal will receive the SIGHUP signal, then the process received SIGHUP signal will be how to deal with it, see the same excerpt from the Baidu Encyclopedia of the word
The system's default processing of the SIGHUP signal is to terminate the process of receiving the signal. So if the signal is not captured in the program, the process exits when the signal is received.
That is, closing the terminal process will receive the SIGHUP signal, and the default way to handle this signal is to end the process, of course, we can also capture processing the signal itself, or ignore it, such as the following code
<?phppcntl_signal (SIGHUP, function () { //This place processes the signal in a way we simply write a log into the file file_put_contents (' Logs.txt ', ' PID: '. Posix_getpid (). ' receive SIGHUP signal '. PHP_EOL);}); while (1) { sleep (ten); Pcntl_signal_dispatch ();}
We run the routine on the command line, then close the Shell Terminal window directly and then reopen a terminal to see if the process is still running:
[Root@localhost php]# Ps-ef | grep deadloop.php Root 16112 1 0 17:20? 00:00:00 php deadloop.phproot 16138 16115 0 17:24 pts/4 00:00:00 grep deadloop.php[root@localhost php]# Cat Logs.txt pid:16112 receive SIGHUP signal
You can see that the deadloop.php is still running, and its parent process becomes the INIT process (because it was adopted by the INIT process because its parent process was exited), and from the file content that was written to it, you can see that the shutdown terminal process received a SIGHUP signal. In fact, we don't have to be so troublesome, we just need to use the Nohup command provided by Linux, but when we start the process with nohup, the process ignores the received SIGHUP signal and does not exit, first removing the signal processing code. Then Nohup run.
[Root@localhost php]# nohup php deadloop.php nohup: Ignore input and append output to ' nohup.out '
and nohup By default will redirect the output of the program to the Nohup.out file in the current directory, or write $homepath if there is no writable permission/nohup.out
[Root@localhost php]# lscmd.sh deadloop.php getphoto.php nohup.out pics[root@localhost php]# Tail- F nohup.out 14709997721470999775147099977814709997811470999784147099978714709997901470999793147099979614709997991470999802
When the terminal is closed, the process does not end, but instead becomes the orphan process (ppid=1) because the parent process that created it exits.
[Root@localhost ~]# Ps-ef | grep 3554root 3554 3497 0 19:09 pts/0 00:00:00 php deadloop.phproot 3575 3557 0 19:10 pts /1 00:00:00 grep 3554[root@localhost ~]# ps-ef | grep 3554root 3554 1 0 19:09? 00:00:00 php deadloop.phproot 3577 3557 0 19:10 pts/1 00:00:00 grep 3554[root@localhost ~]#
Conclusion: So when we combine nohup and & two ways, the process started does not occupy the console, nor does it depend on the console, and the process is adopted by process 1th as the orphan process, which is very similar to the daemon mechanism.
[Root@localhost php]# nohup php deadloop.php >logs.txt 2>error.txt &[1] 3612[root@localhost php]# ps-ef |grep 3 612root 3612 3557 0 19:18 pts/1 00:00:00 php deadloop.phproot 3617 3557 0 19:19 PTS/1 00:00:00 grep 3612[root@localhost php]#
where >logs.txt redirects the standard output, 2>error.txt redirects the standard error output.
The above is the introduction of the first realization method.
The second implementation is based on the rules and characteristics of the daemon through the code to achieve, the most important feature of the daemon is out of the user terminal and session, the following is the implementation of the Code, the key place is commented.
<?php$pid = Pcntl_fork (); if ($pid = =-1) { throw new Exception (' Fork sub process failed ');} ElseIf ($pid > 0) { //parent process exits, the subprocess is not the process leader so that a new session exit (0) can be created successfully;} The most important step is to create a new session out of the original control Terminal posix_setsid ();//Modify the working directory of the current process, as the child process inherits the working directory of the parent process and modifies the working directory to release the occupation of the parent process's working directory. ChDir ('/'); */* Through the previous step, we created a new session leader, process leader, and out of the terminal, but the conversation leader can request to reopen a terminal, in order to avoid this situation, we create a sub-process again, and exit the current process, so that the process is no longer the session leader. */$pid = Pcntl_fork (); if ($pid = =-1) { throw new Exception (' Fork sub process failed ');} ElseIf ($pid > 0) { // once again exit the parent process, the child process becomes the final daemon exit (0);} Because the daemon does not use standard input and output, turn off standard input, output, error output descriptor fclose (STDIN), fclose (STDOUT); fclose (STDERR);/* * Processing Business code */while (TRUE) { File_put_contents (' Log.txt ', Time (). Php_eol, file_append); Sleep (5);}