Unix环境高级编程笔记 :1三、守护进程

1 守护进程
    守护进程也称精灵进程(daemon)是生存期较长的一种进程。它们经常在系统自举时启动,仅在系统关闭时才终止。
    由于没的控制终端,因此它们是在后台运行的。
 
二、守护进程特征
    父进程ID为0的各进程通用是内核进程,它们做为系统自举过程当中的一部分启动
    内核进程是特殊的,通用存在于系统的整个生命周期。它们以超级用户特权运行,无控制终端,无命令行。
 
    进程1一般是init,它是一个系统守护进程,负责启动各运行层次特定的系统服务。
 
    portmap网络端口映射服务
    syslogd守护进程把系统消息记入日志的任何程序使用
    xinted 侦听网络接口,取得来自网络的对各类网络服务进程的请求。  nfsd lockd rpciod
    cron
 
三、编程规则
    1)umask将文件模式建立屏蔽字设置为0    
    2)调用fork,而后使父进程退出
    3)调用setsid以建立一个新会话
    4) 将当前工做目录更改成根目录
    5)关闭再也不须要的文件描述符
    6)某些守护进程打开/dev/null使其具备文件描述符0、一、2,这样任何一个试图读标准输入、写标准输出或标准出错的库例程都不会产生任何效果。
    
 
daemonize.c  想初始化成为一个守护进程的程序调用。    
#include <stdio.h>
#include <syslog.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
 
void daemonize(const char *cmd) {
int i,fd0,fd1,fd2;
pid_t pid;
struct rlimit r1;
struct sigaction sa;
 
umask(0);
 
if(getrlimit(RLIMIT_NOFILE,&r1) < 0) {
printf("%s:can`t get file limit",cmd);
exit(1);
}
if(pid=fork()) < 0) {
printf("%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) {
printf("%s:can`t ignore SIGHUP");
exit(1)
}
if((pid = fork)) < 0) {
printf("%s:can`t fork")
exit(1);
}
else if(pid != 0) {
exit(0)
}
 
if(chdir("/") < 0) {
printf("%s:can`t change directory to /");
exit(1);
}
 
if(r1.rlim_max == RLIM_INFINITY)
r1.rlim_max = 1024;
for(i=0;i<r1.rlim_max;i++) {
close(i);
}
 
 
fd0 = open("/dev/null",O_RDWR);
fd1 = dup(0);
fd2 = dup(0);
 
openlog(cmd,LOG_CONS,LOG_DAEMON);
if(fd0 !=0 ||fd1 != 1||fd2!=2) {
syslog(LOG_ERR,"unexpected file descriptors %d %d %d",fd0,fd1,fd2);
exit(1);
}
}
 
#include <unistd.h>
int daemon(int nochdir,int noclose);
 
在建立精灵进程的时候,每每须要将精灵进程的工做目录修改成"/"根目录 
而且将标准输入,输出和错误输出重定向到/dev/null 

daemon的做用就是当参数nochdir为0时,将根目录修改成工做目录 
noclose为0时,作输入,输出以及错误输出重定向到/dev/null 
 
#include <unistd.h>
int main(int argc, char *argv[])
{
    ...
    if (daemon(0, 0)) {//调用glibc库函数daemon,建立daemon守护进程
        perror("daemon");
        return -1;
    }
    好了执行到这里的就是daemon的子进程了[luther.gliethttp].
    ...
}
 
四、出错记录
    三种方式产生日志消息
    1)内核例程能够调用log函数
    2)用户进程(守护进程)调用syslog(3)函数以产生日志消息
    3)在此主机上的一个用户进程
 
    #include <syslog.h>
    openlog
    syslog
    closelog
    setlogmask
相关文章
相关标签/搜索