守护进程(daemon)就是一直在后台运行的进程(daemon)。守护进程通常有以下几个特点:
1.后台运行。
2.没有控制终端,终端名设置为?号:也就意味着没有stdin0、stdout1、stderr2。
3.父进程不是用户创建的进程,init进程或者systemd(pid=1)以及用户人为启动的用户层进程一般以pid=1的进程为父进程,而以kthreadd内核进程创建的守护进程以kthreadd为父进程。
4.守护进程一般是会话首进程、组长进程。
5.工作目录为(根目录),主要是为了防止占用磁盘导致无法卸载磁盘。
使用场景守护进程一般用于监控其他程序运行情况和执行定时任务。
创建守护进程要创建一个守护进程,一般进行如下步骤:
如果是单例守护进程,结合锁文件和kill函数检测是否有进程已经运行。
umask取消进程本身的文件掩码设置,也就是设置Linux文件权限,一般设置为,这是为了防止子进程创建一个不能访问的文件(没有正确分配权限)。此过程并非必须,如果守护进程不会创建文件,也可以不修改。
fork出子进程,父进程退出。这样子进程一定不是组长进程(进程id不等于进程组id)。
子进程调用setsid新建会话(使子进程变为会话首进程、组长进程,并断开终端)。
如果是单例守护进程,将pid写入到记录锁文件,一般为/var/run/xxx.pid。
切换工作目录到根目录,这是为了防止占用磁盘造成磁盘不能卸载。所以也可以改到别的目录,只要保证目录所在磁盘不会中途卸载。
重定向输入输入错误文件句柄,将其指向/dev/null。
下面以PHP的实现方式为例来说明。在说明之前先介绍几个PHP函数。如下:
pcntl_fork:在当前进程内创建一个子进程。成功时,在父进程执行线程内返回产生的子进程的PID,在子进程执行线程内返回0。失败时,在父进程上下文返回-1,不会创建子进程,并且会引发一个PHP错误。
posix_setuid:设置当前进程的操作用户
posix_setgid:设置当前进程的操作用户所属分组
getmypid:获取当前进程id
posix_kill:向指定进程发送进程信号
pcntl_signal:安装一个信号处理器
system:执行外部程序,并且显示输出
1、启动守护进程2、停止守护进程停止守护进程,只需读取守护进程的pid文件,然后调用PHP函数posix_kill(pid,9),最后将该文件删除,即可。如下:
3、重启守护进程重启守护进程,就是给守护进程发送SIGHUP信号。发送SIGHUP信号,既可以通过Linux命令kil发送kill-sSIGHUP,也可以通过PHP库函数posix_kill(posix_getpid(),SIGUSR1)实现。如下:
4、完整代码注意事项1、不要使用超级用户启动守护进程,因为这样一旦由于程序出现漏洞被骇客控制,攻击者只能继承运行权限,而无法获得超级用户权限。
2、守护进程只能运行一个,不能同时开启多个。
好啦,今天萌萌的干货就分享到这啦
如果你想拥有更多学习与交流的机会
想与更多的大神切磋和咨询经验
赶快添加下方