UNIX环境C语言编程(10)-守护进程
2015-02-04 17:22
302 查看
1、守护进程的特征
•英文名称daemon,又称为常驻进程、精灵进程
•守护进程有以下特征:
•1、长时间后台运行,通常随系统启停而启停
•2、大多系统守护进程具有root权限
•3、没有控制终端
•4、所有用户级别(非内核级别)的守护进程都是进程组长、会话领导,
并且是进程组与会话中的唯一一组进程
•5、大多守护进程的父进程都是init进程
2、编码规则
•如果编码实现一个守护进程,需要考虑哪些因素:
•1、将文件创建掩码umask设置为0
•2、调用fork,然后父进程退出,目的:
shell能够接收下一条指令;
子进程不是进程组长,这是调用setsid函数的先决条件
•3、调用setsid创建一个新的会话
当前进程成为新会话的领导、成为新进程组的组长、没有控制终端
•4、将当前工作目录改变为根目录/
•5、关闭不再需要的文件描述符
•6、一些daemon进程将描述符0、1、2重定向为/dev/null设备
3、单实例守护进程
•即只能启动一个实例,不能多个实例同时运行
•如果做到这一点?
•文件与记录锁机制提供了一种简便的互斥机制
•一个进程放置“写”锁后,其它进程后续的加锁尝试都会失败
•另外,进程退出后,文件锁会自动释放,免除了手工清理的麻烦
•文件锁机制在下一章节详述,一个简单示例:
4、守护进程的惯例
•系统的守护进程在收到SIGHUP信号后,会重新读取配置文件
5、客户机/服务器模型
•守护进程通常充当一个服务器,等待客户端请求,并处理
•后续章节会看到更多的双向通信的示例:
•客户端发送请求,服务器处理并且,并发送响应结果
•英文名称daemon,又称为常驻进程、精灵进程
•守护进程有以下特征:
•1、长时间后台运行,通常随系统启停而启停
•2、大多系统守护进程具有root权限
•3、没有控制终端
•4、所有用户级别(非内核级别)的守护进程都是进程组长、会话领导,
并且是进程组与会话中的唯一一组进程
•5、大多守护进程的父进程都是init进程
2、编码规则
•如果编码实现一个守护进程,需要考虑哪些因素:
•1、将文件创建掩码umask设置为0
•2、调用fork,然后父进程退出,目的:
shell能够接收下一条指令;
子进程不是进程组长,这是调用setsid函数的先决条件
•3、调用setsid创建一个新的会话
当前进程成为新会话的领导、成为新进程组的组长、没有控制终端
•4、将当前工作目录改变为根目录/
•5、关闭不再需要的文件描述符
•6、一些daemon进程将描述符0、1、2重定向为/dev/null设备
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <signal.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> void z_daemon(void) { pid_t childpid = 0; struct sigaction sa; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; /* 忽略信号 */ sa.sa_handler = SIG_IGN; sigaction(SIGQUIT, &sa, NULL); sigaction(SIGHUP, &sa, NULL); sigaction(SIGINT, &sa, NULL); sigaction(SIGPIPE, &sa, NULL); #ifdef SA_NOCLDSTOP sa.sa_flags |= SA_NOCLDSTOP; #endif #ifdef SA_NOCLDWAIT sa.sa_flags |= SA_NOCLDWAIT; #endif sigaction(SIGCHLD, &sa, NULL); if( getppid() == 1 ) return; fflush(stdout); fflush(stderr); umask(0); childpid = fork(); if( childpid < 0 ) exit(0); else if( childpid > 0 ) exit(0); /* the first child process */ if( setsid() == (pid_t) (-1) ) exit(0); childpid = fork(); if( childpid < 0 ) exit(0); else if( childpid > 0 ) exit(0); /* the second child process */ return; }
3、单实例守护进程
•即只能启动一个实例,不能多个实例同时运行
•如果做到这一点?
•文件与记录锁机制提供了一种简便的互斥机制
•一个进程放置“写”锁后,其它进程后续的加锁尝试都会失败
•另外,进程退出后,文件锁会自动释放,免除了手工清理的麻烦
•文件锁机制在下一章节详述,一个简单示例:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <fcntl.h> #include <unistd.h> #include <sys/stat.h> #define LOCKFILE "daemon.pid" #define LOCKMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) int already_running(void) { int fd; char buf[16]; fd = open(LOCKFILE, O_RDWR|O_CREAT, LOCKMODE); if( fd < 0 ) { printf("can't open %s: %s\n", LOCKFILE, strerror(errno)); exit(1); } if( lockf(fd, F_TLOCK, 0) < 0 ) { if( errno == EACCES || errno == EAGAIN ) { close(fd); return(1); } printf("can't lock %s: %s\n", LOCKFILE, strerror(errno)); exit(1); } ftruncate(fd, 0); sprintf(buf, "%ld", (long)getpid()); write(fd, buf, strlen(buf) + 1); return(0); } int main(void) { if( already_running() ) { printf("already running ...\n"); exit(0); } printf("ok\n"); sleep(100); }
4、守护进程的惯例
•系统的守护进程在收到SIGHUP信号后,会重新读取配置文件
5、客户机/服务器模型
•守护进程通常充当一个服务器,等待客户端请求,并处理
•后续章节会看到更多的双向通信的示例:
•客户端发送请求,服务器处理并且,并发送响应结果
相关文章推荐
- UNIX环境高级编程——守护进程列表
- UNIX环境高级编程——单实例的守护进程
- UNIX环境高级编程-第13章- 守护进程
- Unix环境高级编程笔记 :13、守护进程
- UNIX高级环境编程: 终端登录过程-远程登录-进程组-Session-Linux启动过程-dup与重定向-守护进程
- UNIX环境高级编程——守护进程
- UNIX环境高级编程——守护进程
- Unix环境编程:进程组,会话与守护进程
- Unix环境高级编程:守护进程
- Unix 环境高级编程(APUE) 之 七 进程关系 和 守护进程
- UNIX环境高级编程学习之第十三章守护进程 - 单实例的守护进程
- UNIX环境C语言编程(7)-进程控制
- UNIX环境高级编程学习之第十三章守护进程 - 初始化一个守护进程
- Unix环境高级编程——守护进程记录总结(从基础到实现)
- UNIX环境高级编程——守护进程
- UNIX环境高级编程——初始化一个守护进程
- UNIX环境高级编程——单实例的守护进程
- UNIX环境C语言编程(8)-进程关系
- UNIX环境高级编程——单实例的守护进程
- unix环境高级编程-守护进程