守护进程
什么是守护进程
守护进程是生存期长的一种进程。他们常在系统引导时装入,仅在系统关闭时才终止。因为他们没有控制终端,所以说他们是后台运行的。
如何创建守护进程
1.调用umask将文件模式创建屏蔽字设置为一个已知值(通常是0).
2.调用fork(),然后使父进程exit。
1.如果该守护进程是作为shell命令启动的,可以让shell以为该命令已执行完毕
2.保证该进程不是一个进程组的组长进程
3.调用setsid创建一个新会话
1.成为新会话首进程
2.成为新进程组,组长进程
3.无控制终端
4.将当前目录更改为根目录
5.关闭不再需要的文件描述符
6.某些守护进程打开/dev/null/使其具有文件描述符,这样任何一个企图读标准输入,写标准输出,错误输出的都不会产生效果。
注:也可以在第三步后再次fork,终止父进程,保证该进程不是会话首进程
实例:
#include<apue.h>
#include<syslog.h>
#include<fcntl.h>
#include<sys/resource.h>
void demonize(const char *cmd)
{
int i,fd0,fd1,fd2;
pid_t pid;
struct rlimit rl;
struct sigaction sa;
umask(0); //设置文件创建屏蔽字
if((pid=fork())<0)
err_quit("%s;can't fork",cmd);
else if(pid!=0)
exit(0); //父进程
setsid();
sa.sa_handler=SIG_IGN;
sigemptyset(&sa.sa_mask);
sa.sa_flags=0;
if(sigaction(SIGHUP,&sa,NULL)<0)
err_quit("%s:can't ignore SIGHUP",cmd);
if((pid=fork())<0)
err_quit("%s,can't fork",cmd);
else if(pid!=0)
exit(0);
if(chdir("/")<0)
err_quit("%s,can't chdir",cmd);
if(getrlimit(RLIMIT_NOFILE,&rl)<0)
err_quit("%s:can't get gile limit",cmd);
if(rl.rlim_max==RLIM_INFINITY)
rl.rlim_max=1024;
for(i=0;i<rl.rlim_max;i++)
close(i);
fd0=open("/dev/null",O_RDWR);
fd1=dup(0);
fd2=dup(0);
}
int main()
{
demonize("hello");
sleep(60);
}