The php daemon plus the linux command nohup implements the task once per second

  • 2020-05-09 18:17:59
  • OfStack

The nohup command function in Unix is to run the command without hanging up, while nohup puts all the output of the program into the nohup.out file in the current directory or, if the file is not writable, into the nohup.out file < User home directory > / nohup.out file. So with this command we'll write php as shell script and use a loop to keep our script 1 running, whether or not our terminal window is closed we'll keep our php script 1 running.
Write a small PHP program that records time every 30 seconds and writes it to a file
 
# vi for_ever.php 
#! /usr/local/php/bin/php 
define('ROOT', dirname(__FILE__).'/'); 
set_time_limit(0); 
while (true) { 
file_put_contents(ROOT.'for_ever.txt', date('Y-m-d H:i:s')."\n", FILE_APPEND); 
echo date('Y-m-d H:i:s'), ' OK!'; 
sleep(30); 
} 
?> 

Save exit, and then give the for_ever.php file executable permissions:
# chmod +x for_ever.php
Make it execute in the background:
# nohup /home/andy/for_ever.php.php &
Remember to add at the end & Symbol, so you can run it in the background
The following prompt appears after executing the above command:
[1] 5157
nohup: appending output to 'nohup.out'
All command execution output information is placed in the nohup.out file
At this point you can open for_ever.txt and nohup.out in the same directory as for_ever.php!
Well, it's going to run forever. How do you end it?
# ps
PID TTY TIME CMD
4247 pts/1 00:00:00 bash
5157 pts/1 00:00:00 for_ever.php
5265 pts/1 00:00:00 ps
# kill -9 5157
Go to process 5157 to kill it, you will see
[1]+ Killed nohup /home/andy/for_ever.php
OK!
====================
In many projects, there may be a number of similar back-end scripts that need to be periodically executed through crontab. Let's say I check the user status every 10 seconds. The script is as follows:
@file: /php_scripts/scan_userstatus.php
 
#!/usr/bin/env php -q 
$status = has_goaway(); 
if ($status) { 
//done 
} 
?> 

Periodically execute the script scan_userstatus.php via crontab
#echo "*:*/10 * * * */ php_scripts/ scan_userstatus.php"
This way, the script is executed every 10 seconds.
We found that the script's memory resources had not been freed in a short time, and the new script was enabled. That is to say: the new script started, the old script occupied resources have not been released as expected. So, over time, a lot of memory resources are wasted. We have made a few improvements to this script, which are as follows:
@file: /php_scripts/scan_userstatus.php
 
#/usr/bin/env php -q 
while (1) { 
$status = has_goaway(); 
if ($status) { 
//done 
} 
usleep(10000000); 
} 
?> 

So you don't need crontab anymore. You can execute the script with the following command to achieve the same functional effect
#chmod +x /php_scripts/scan_userstatus.php
#nohup /php_scripts/scan_userstatus.php &
Here we go through & We put the script in the background and used the nohup command to prevent the process from being killed as the terminal session window closes. So is there a way to run the nohup command without making it work, like Unin/Linux Daemon1? Next, we'll talk about daemon functions.
What is a daemon? A daemon is usually thought of as a background task that does not control the terminal. It has three distinct features: it runs in the background, is disconnected from the process that started it, and does not need to control the terminal. The common implementation is fork() - > setsid() - > fork() details are as follows:
@file: /php_scripts/scan_userstatus.php
 
#/usr/bin/env php -q 
daemonize(); 
while (1) { 
$status = has_goaway(); 
if ($status) { 
//done 
} 
usleep(10000000); 
} 
function daemonize() { 
$pid = pcntl_fork(); 
if ($pid === -1 ) { 
return FALSE; 
} else if ($pid) { 
usleep(500); 
exit(); //exit parent 
} 
chdir("/"); 
umask(0); 
$sid = posix_setsid(); 
if (!$sid) { 
return FALSE; 
} 
$pid = pcntl_fork(); 
if ($pid === -1) { 
return FALSE; 
} else if ($pid) { 
usleep(500); 
exit(0); 
} 
if (defined('STDIN')) { 
fclose(STDIN); 
} 
if (defined('STDOUT')){ 
fclose(STDOUT); 
} 
if (defined('STDERR')) { 
fclose(STDERR); 
} 
} 
?> 

After the daemon function is implemented, a resident process can be established, so it only needs to be executed once:
#/php_scripts/scan_userstatus.php
The two key php functions here are pcntl_fork() and posix_setsid(). fork()1 process means that a copy of a running process has been created, which is considered a child process, and the original process is considered a parent process. When fork() is running, it can be separated from the process that started it, terminal control, etc., which also means that the parent process can exit freely. pcntl_fork() returns a value of -1 for failed execution, 0 for child, and ID for parent. In this case, exit the parent process. setsid(), which first makes the new process the "leader" of a new session, and finally makes the process no longer control the terminal, is the most critical step of the daemon, which means that the terminal is not forced to exit the process. This is a critical step for a resident process that will not be interrupted. Perform fork() for the last time. This step is not required, but it is usually done, and its greatest significance is to prevent the acquisition of the control terminal. A control terminal is obtained when a terminal device is opened directly and the O_NOCTTY flag is not used.
Other notes:
1) chdir() places daemons in directories that always exist. Another benefit is that your resident process will not limit you to umount1 file systems.
2)umask() set the file mode and create the mask to the maximum allowed limit. If a daemon needs to create a file with readable, writable permissions, an inherited mask with stricter permissions can have the opposite effect.
3) fclose(STDIN), fclose(STDOUT), fclose(STDERR) close the standard I/O streams. Note that if there is output (echo), the daemon will fail. Therefore, STDIN, STDOUT, STDERR are usually redirected to a specified file.

Related articles: