守护进程是指在后台进程运行的,没有控制终端与之相连的进程,他独立于控制终端,通常周期的执行某种任务。
编写守护进程的时候,要尽量避免不必要的交互。
(1)让进程在后台执行。方法是调用一个fork产生一个子进程,然后使得父进程退出。
当判断其为父进程时直接终止改进程即可。
(2)调用setsid创建一个新的会话周期,控制终端,登录会话和进程组通常是从父进程继承下来的,守护进程要摆脱他们,不受其影响,其方法是调用setsid使进程成为一个会话组长。(当进程是会话组长时,调用setsid会失败,但第一点已经保证进程不会是会话组长,setsid调用成功后,进程成为新的会话组长和进程组长,并与原来的登录会话和进程组脱离,由于会话过程对控制终端的独占性,进程同时与控制终端脱离。)
具体步骤只需在需要的进程中执行setsid()即可。
(3)禁止进程重新打开控制终端。经过上述步骤,进程已经成为一个无终端的会话组长了,但是他可以重新申请打开一个终端,为了避免这种情况的发生,可以通过使进程不再是会话组长来实现。再一次通过fork创建新进程,使已经是进程组长的父进程退出,用子进程运行,因为子进程不是进程组长所以无法重新申请打开一个新进程。
步骤与第一步相同。
(4)关闭不需要的文件描述符,创建子进程从父进程继承打开的文件描述符,如不关闭,将会浪费系统资源,造成进程所在的文件系统无法卸下以及引起无法预料的错误,先得到最高文件描述符值,然后用一个循环程序,关闭0到最高文件描述符值的所有文件描述符。
(5)将当前工作目录改变为根目录,当守护进程当前工作目录在一个装配文件系统中,该文件系统不能被拆卸。一般需要将工作目录改为根目录。
(6)将文件创建时使用的屏蔽字设置为0。进程从创建他的父进程哪里继承的文件创建屏蔽字可能会拒绝某些许可全。为防止这一点,使用umask(0)将屏蔽字清零。