本次将记录有关Linux守护进程的概念及其用法。
守护进程是我们通常说的Daemon进程,是后台服务进程,通常独立于控制终端并周期性地执行任务或等待事件。守护进程常在系统引导装入时启动,在系统关闭时终止。在Linux中,每一个从终端运行的进程都会依附于这个终端,当终端被关闭时,进程会自动关闭。但是守护进程就能突破这种限制,如果想让某个进程不因为用户或终端的变化而受到影响,则应该把这个进程变成守护进程。
编写守护进程的步骤:
1.创建子进程,退出父进程
退出父进程后,子进程变成孤儿进程,由1号进程(init进程)收养。
关键代码如下:
pid = fork();
if (pid > 0)
{
exit(0);
}
2.在子进程中创建新会话
先介绍两个概念:进程组和会话组
进程组是一个或多个进程的集合,由进程组ID唯一标识。每个进程组都有组长进程,组长的进程号就是进程组ID,且该进程组ID不会因组长进场的退出而受到影响。
会话组是一个或多个进程组的集合,通常来说,会话始于用户登录,终止于用户退出。
接下来重点介绍setsid函数,它是创建守护进程的最重要一环。setsid函数用于创建一个新的会话,并担任会话组的组长。setsid函数的作用有3点
(1)让进程摆脱原会话组的控制
(2)让进程摆脱原进程组的控制
(3)让进程摆脱原控制终端的控制
为什么要执行setsid函数呢?原因是,之前我们利用fork函数创建子进程的时候,把父进程的会话组、进程组、控制终端等信息都复制过来了,虽然父进程退出了,但是子进程还是会保留这些信息的。所以我们需要执行setsid函数来改变这些信息,进行“越狱”。
prototype : pid_t setsid(void)
return : 该进程组ID —— success
-1 —— failure
3.改变当前目录为根目录
一般子进程继承父进程的当前目录环境下的文件系统是不能卸载的,对以后使用可能会有麻烦(如系统需要进入单用户模式)。通常的做法是把根目录“/”作为守护进程的当前工作目录。
4.重设文件权限掩码
子进程继承父进程的权限掩码,带来不便,一般把掩码重设为0,较为灵活。
5.关闭文件描述符
子进程会从父进程那里继承一些已经打开了的文件,它们在消耗着系统资源。由于子进程已经脱离了终端的控制,文件描述符为0、1、2的文件(输入、输出、报错)也失去了存在价值,应被关闭。
摘自《嵌入式Linux应用程序开发详解》的例程如下:
编译运行后,执行tail -f /tmp/dameon.log 即可查询到该文件周期性更新的效果。
执行 ps -ef | grep daemon 即能查询到守护进程的状态。
本节完。