Linux 守护进程


如何实现守护进程

1、在后台运行

为了避免挂起终端退出,在进程中调用fork,然后使父进程退出,变成孤儿进程后在后台运行,此时子进程由init进程收养

1
2
3
if(pid=fork())
exit(0);//是父进程,结束父进程,子进程继续
>

2、脱离控制终端,登录会话和进程组

控制终端,登录会话和进程组通常是从父进程继承下来的。我们的目的就是要摆脱它们,使之不受它们的影响。方法是在第1点的基础上,调用setsid()使进程成为会话组长

1
2
setsid();
>

3、 禁止进程重新打开控制终端

进程已经成为无终端的会话组长。但它可以重新申请打开一个控制终端。可以通过使进程不再成为会话组长来禁止进程重新打开控制终端

1
2
3
if(pid=fork())
exit(0);//结束第一子进程,第二子进程继续(第二子进程不再是会话组长)
>

4、关闭打开的文件描述符

进程从创建它的父进程那里继承了打开的文件描述符。如不关闭,将会浪费系统资源,造成进程所在的文件系统无法卸下以及引起无法预料的错误。按如下方法关闭它们

1
2
3
4
#define NOFILE 256 ;//不同系统中不同数值
for(i=0;i<NOFILE;i++)
colse(i);
>

5、改变当前工作目录

进程活动时,其工作目录所在的文件系统不能卸下。一般需要将工作目录改变到根目录。对于需要转储核心,写运行日志的进程将工作目录改变到特定目录如/tmpchdir(“/“)

1
2
chdir("/");
>

6、重设文件创建掩码

进程从创建它的父进程那里继承了文件创建掩模。它可能修改守护进程所创建的文件的存取位。为防止这一点,将文件创建掩模清除0

1
2
umask(0);
>

7、处理SIGCHLD(子进程退出信号)信号

处理SIGCHLD信号并不是必须的。但对于某些进程,特别是服务器进程往往在请求到来时生成子进程处理请求。如果父进程不等待子进程结束,子进程 将成为僵尸进程(zombie)从而占用系统资源。如果父进程等待子进程结束,将增加父进程的负担,影响服务器进程的并发性能。在Linux下可以简单地 将SIGCHLD信号的操作设为SIG_IGN

1
2
signal(SIGCHLD,SIG_IGN);
>