什么是守护进程?
守护进程(daemon)指具有特殊用途的进程(一般用于给其他进程提供服务);
守护进程有哪些特征?
守护进程是生存期长---通常在系统引导时启动,在系统关闭时才终止;
守护进程在后台运行;
守护进程没有控制终端用来读取或写入数据;
系统进程依赖于操作系统实现,父进程ID为0的各进程通常是内核进程;
他们作为系统引导装入过程的一部分而启动;
(init是一个由内核在引导装入时启动的用户层次的命令)
内核进程说特殊的,通常存在于系统的整个生命周期中;它们以超级用户特权运行;
无控制终端,无命令行;
ps的输出实例中,内核守护进程的名字出现在方括号中;
linux中用一个名为kthread的特殊内核进程来创建其他内核进程,kthread表现为其他内核进程中父进程;
对于需要在进程上下文执行工作但却不被用户层进程上下文调用的每一个内核组件,通常有他自己的内核守护进程;
进程1通常时init进程;init进程是一个系统守护进程,除了其他工作外主要负责启动运行层次特定的系统服务;
rpcbind守护进程提供将远程过程调用(Remote Procedure Call,RPC)程序号映射为网络端口号的服务;
inetd守护进程负责侦听系统网络接口,以便取得来自网络的对各种网络服务守护进程提供对网络文件系统(Network File System,NFS)
用户级守护进程和内核级守护进程?
大多数守护进程都以超级用户进程(root)特权运行;
所有的守护进程都没有控制终端,其终端名设置为问号;
内核守护进程以无控制终端方式启动;
用户层守护进程缺少控制终端可能是守护进程调用了setsid的结果;
大多数用户层守护进程都是进程组的组长进程以及会话的首进程,这些进程组和会话中的唯一进程;
用户层守护进程的父进程是init进程;
如何创建守护进程?
首先要做的是调用umask将文件模式创建屏蔽字设置为一个已知值(通常是0);由继承得来得文件模式创建屏蔽字可能会被设置为拒绝某些权限;如果守护进程要创建文件,那么它可能要设置特定得权限;
若守护进程要创建组可读、组可写得文件,继承的文件模式创建屏蔽字可能会屏蔽上述两种权限的一种,而使其无法发挥作用;另一方面,如果守护进程调用的库函数创建了文件,那么将文件模式创建屏蔽字设置为一个限制性更强的值(如007)可能会更明智,因为库函数可能不允许调用者通过一个显式的函数参数来设置权限;
调用fork,然后使父进程exit;第一,如果该守护进程是作为一条简单的shell命令启动的,那么父进程终止会让shell认为这条命令已经执行完毕;第二,虽然子进程继承了父进程的进程组ID,但获得了一个新的进程ID,这就保证了子进程不是一个进程组的组长进程;这是下面要进行的setsid调用的先决条件;
调用setid创建一个新会;然后执行3个步骤,使调用进程:1.称为新会话的首进程;2.称为一个新进程组的组长进程;3.没有控制终端;
将当前工作目录更改为根目录;从父进程处继承过来的当前工作目录可能在一个挂载的文件系统中;因为守护进程通常在系统引导之前是一直存在的,所以如果守护进程的当前工作目录在一个挂载文件系统中,那么该文件系统就不能被卸载;或者,某些守护进程还可能会把当前工作目录更改到某个指定位置,并在此位置进行它们的全部工作;
关闭不再需要的文件描述符;这使守护进程不再持有从其父进程继承来的任何文件描述符;
某些守护进程打开dev/null使其具有文件描述符0、1和2,这样,任何一个试图读标准输入、写标准输出或标准错误的库例程都不会产生任何效果;因为守护进程并不与终端设备相关联,所以其输出无处显示,也无处从交互式用户那里接收输入;即使守护进程是从交互式会话启动的,但是守护进程是在后台运行的,所以登录会话的终止并不影响守护进程;如果其他用户在同一终端设备上登录,我们不希望在该终端上见到守护进程的输出,用户也不期望他们在终端上的输入守护进程读取;
守护进程在一个孤儿进程组中,它不是会话首进程,因此没有机会被分配到一个控制终端;
守护进程应当如何处理出错消息?
守护进程有3种产生日志消息的方法:
内核例程可以调用log函数;任何一个用户进程都可以通过打开(open)(read)/dev/klog设备来读取这些信息;
大多数用户进程(守护进程)调用syslog(3)函数来产生日志消息;消息被发送至UNIX域数据报套接字/dev/log;
无论一个用户进程是在此主机上,还是在TCP/IP网络连接到此主机的其他主机上,都可将日志消息发向UDP端口514;
单实例守护进程?
为了正常运作,某些守护进程会实现为,在任一时刻只运行该守护进程的一个副本;如,这种守护进程可能需要排它地访问一个设备;
如果守护进程需要访问一个设备,而该设备驱动程序有时会阻止想要多次打开/dev目录下相应设备节点的尝试;这就限制了在一个时刻只能运行守护进程的一个副本;但是如果没有这种设备可用,那么我们需要自行处理;
文件和记录锁提供了一种方便的互斥机制;如果守护进程在一个文件的整体上得到一把写锁,那么在该守护进程终止时,这把锁将被自动删除;这就简化了复原所需的处理,去除了对以前的守护
守护进程的惯例
若守护进程使用锁文件,那么该文件存储在/var/run目录中;然而需要注意的是,守护进程可能需要具有具有超级用户权限才能在此目录下创建文件;锁文件的名字通常是name,pid,其中,name是该守护进程或服务的名字;
若守护进程支持配置项,那么配置文件通常存放在/etc目录中;配置文件的名字通常是name,conf,其中,name是首进程或服务的名字;如,syslogd守护进程的配置文件通常是/etc/syslog.conf;
守护进程可用命令行启动,但通常它们是由系统初始化脚本之一(/etc/rc*或/etc/init.d/*)启动的;如果在守护进程终止时,应当自动地重新启动它,则我们可在/etc/inittab中为该守护进程包括respawn记录项,这样,init就将重新启动该守护进程;
若一个守护进程有一个配置文件,那么当该守护进程启动时会读该文件,但在此之后一般就不会再查看它;若某个管理员更改了配置文件,那么守护进程可能需要被停止,然后再启动,以使配置文件的更改生效;为避免此种麻烦,某些守护进程将捕捉SIGHUP信号,当他们接收到该信号时,重新读配置文件。因为守护进程并不与终端相结合,它们或者是无控制终端的会话首进程,或者是孤儿进程组的成员,所以守护进程没有理由期望接收SIGHUP;于是,守护进程客户以安全地重复使用SIGHUP;
客户进程常常用作服务器进程;如syslogd进程为服务器进程,用户进程(客户进程)用UNIX域数据报套接字向其发送信息;
一般而言,服务器进程等待客户进程与其联系,提出某种类型的服务要求;如syslogd服务器进程提供的服务是将一条出错信息记录到日志文件中;
通常客户进程和服务器进程之间的通信是双向的;客户进程向服务器进程发送服务请求,服务器进程则向客户进程回送应答;
参考书籍:linu/unix系统编程手册