什么是守護進程
守護進程(daemon)是一種特殊的進程,它的生命周期很長,它在后臺運行并且沒有控制終端(這樣可以保證守護進程不會接收到各種來自終端的信號)。比如:crontab、sshd、nginx等,都會使用守護進程的形式運行,確??梢砸恢闭5奶峁┓?。
如何實現(xiàn)守護進程
- fork子進程,父進程退出(當前子進程會成為init進程的子進程)
- 子進程調(diào)用setsid(),開啟一個新會話,成為新的會話組長,并且釋放于終端的關聯(lián)關系
- 再次fork子進程,父進程退出(可以防止會話組長重新申請打開終端)
- 關閉打開的文件描述符
- 改變當前工作目錄chdir
- 清除進程的umask
PHP實現(xiàn)
/** * daemon(守護進程) PHP實現(xiàn) * @author zhjx922 */$pid = pcntl_fork();if ($pid == -1) { die(‘創(chuàng)建子進程失敗’);} else if ($pid) { //第一次退出父進程 exit(0);}//setsidposix_setsid();echo “成功輸出,脫離終端” . PHP_EOL;sleep(5);$pid = pcntl_fork();if ($pid == -1) { die(‘創(chuàng)建子進程失敗’);} else if ($pid) { //第二次退出父進程(之前fork出來的子進程) exit(0);}echo “依然可以輸出” . PHP_EOL;sleep(5);//關閉各種描述符@fclose(STDOUT);@fclose(STDERR);$STDOUT = fopen(‘/dev/null’, “a”);$STDERR = fopen(‘/dev/null’, “a”);chdir(‘/’);umask(0);echo “這里不會輸出, ps aux | grep daemon.php 查看進程,20s后退出” . PHP_EOL;sleep(20);
日常使用已經(jīng)注意事項
- php daemon.php & 這樣使用,當關閉終端后,當前php進程也會同時關掉
- nohup php daemon.php > daemon.log & 終端關閉后,依然會繼續(xù)運行
- 使用supervisor