守护进程详解
守护进程的作用
守护进程(daemon):在后台运行的一种特殊进程,没有控制终端,周期性的运行某项任务。在Linux上很多服务都是以守护进程的形式运行在系统上,如inetd进程侦听系统网络接口,定时任务进程cron。
守护进程实例
在CentOS系统上输入ps命令,查看所有的进程情况(图中列出部分):
注意事项:
- 系统创建守护进程由方括号阔起来:由系统创建的守护进程名由方括号扩起来,[Kthreadd]进程是所有系统守护进程的父进程,Kthreadd进程的进程号为2,可见其他守护进程的父进程为2;
- 守护进程都是与终端分离的,因此其终端(TTY)那一栏显示为“?”,大多数守护进程都是以超级用户root特权运行;
- 进程号为1的进程为init进程,父进程ID为0的进程通常是内核进程;
守护进程特性及构造原理
守护进程特性
- 守护进程要想专注的在系统上周期性执行任务,必须与运行前环境隔离开来。包括:控制终端、父进程的文件描述符、工作目录、文件掩码、会话和进程组等,这些环境通常是由守护进程从其父进程继承而来的。
- 守护进程可以在Linux系统启动时从启动脚本/etc/rc.d中启动,可以由作业规划进程crond启动,还可以由用户终端(通常是 shell)执行。
进程、进程组、控制终端登陆会话之间的关系
- 进程属于一个进程组,进程组号(GID)就是进程组长的进程号(PID);
- 登陆会话可以包含多个进程组,这些进程组共享一个控制终端(这个控制终端通常是创建进程的登陆终端);
守护进程的构造原理(APUE中的创建步骤,实际操作中有些不同)
调用umask将文件模式创建屏蔽字设置为一个已知值(通常为0):
- 由继承而来的文件模式创建屏蔽字可能会被设置为拒绝某种权限;
- 如果守护进程要创建文件,那么它可能要设置特定的权限;
调用fork,然后是父进程exit:
- 如果守护进程是作为一条简单的shell命令启动的,那么父进程种植会让shell认为这条命令已经执行完毕;
- 虽然子进程继承了父进程的进程组ID,但获得了一个新的进程ID,这就保证了紫禁城不是一个进程组的组长ID;
调用setsid创建一个新会话:
- 与原来登陆的会话和进程组脱离,成为新会话的首进程;
- 成为新进程组的组长进程;
- 没有控制终端;
改变当前工作目录:
- 因为守护进程通常在系统再引导之前是一直存在的,所以如果守护进程的当前工作目录一直是存在的,所以如果守护进程的当前工作目录一直挂在文件系统中,那么该文件系统就不能被卸载;
关闭不再需要的文件描述符:
- 守护进程不再持有从父进程继承来的任何文件描述符(父进程可能是shell进程或某个其他进程)
- 可以使用getrlimit来判断最高文件描述符值,并关闭直到该值的所有描述符;
某些守护继承打开/dev/null使其具有文件描述符0、1和2:
- 任何一个试图读标准输入、写标准输出或标准错误的库例程都不会产生任何效果,因为守护进程并不