在 PHP 中如何實(shí)現(xiàn)一個(gè)常駐系統(tǒng)的守護(hù)進(jìn)程呢!使其可以脫離終端運(yùn)行淋叶,不直接將其運(yùn)行結(jié)果輸出到終端践盼。這里列舉兩種實(shí)現(xiàn)方式峡碉。
nohup
通過在命令后追加 "&" 操作符,即可忽略所有的掛斷(SIGHUP)信號岩瘦。
$ nohup php deamon.php &
查看 deamon.php 是否成功被掛起。
$ ps -ef | grep "deamon.php"
root 25462 24539 0 21:16 pts/0 00:00:00 php deamon.php
pcntl擴(kuò)展
代碼
/**
* daemo運(yùn)行
*/
function daemonize() {
global $STDIN, $STDOUT;
//重定向標(biāo)準(zhǔn)輸入和輸出
fclose(STDIN);
fclose(STDOUT);
fclose(STDERR);
$STDIN = fopen('/dev/null', 'r');
$STDOUT = fopen('./out.log', 'a');
posix_setsid();
//fork子進(jìn)程, 主進(jìn)程退出
$pid = pcntl_fork();
if (-1 == $pid) {
die('fork faild!');
} elseif ($pid > 0) {
exit(0);
}
}
daemonize();
$count = 0;
while(true) {
sleep(1);
$count ++;
echo $count, PHP_EOL;
}
運(yùn)行結(jié)果
上述代碼,如果不以守護(hù)態(tài)運(yùn)行厢拭,那么會在終端每隔一秒直接輸出秒數(shù)。
$ php deamon.php
1
2
3
4
...
反之以守護(hù)進(jìn)程運(yùn)行撇叁,echo 不會直接輸出到終端供鸠,而是輸出到 out.log 文件中,這是因?yàn)橐褜?biāo)準(zhǔn)輸出重定向到了 out.log 的文件描述符陨闹。
$ php deamon.php
//終端并未掛起, 查看deamon.php守護(hù)進(jìn)程
$ pstree -a
//查看輸出
$ tailf out.log
40
41
42
43
原理
很簡單楞捂,在終端運(yùn)行腳本時(shí),代碼中會 fork 一個(gè)脫離終端的進(jìn)程趋厉,并退出當(dāng)前腳本寨闹。fork 的進(jìn)程充當(dāng)了守護(hù)進(jìn)程的角色。