《APUE》读书笔记—第十三章守护进程

上传人:平*** 文档编号:15414456 上传时间:2017-11-04 格式:DOCX 页数:9 大小:92.31KB
返回 下载 相关 举报
《APUE》读书笔记—第十三章守护进程_第1页
第1页 / 共9页
《APUE》读书笔记—第十三章守护进程_第2页
第2页 / 共9页
《APUE》读书笔记—第十三章守护进程_第3页
第3页 / 共9页
《APUE》读书笔记—第十三章守护进程_第4页
第4页 / 共9页
《APUE》读书笔记—第十三章守护进程_第5页
第5页 / 共9页
点击查看更多>>
资源描述

《《APUE》读书笔记—第十三章守护进程》由会员分享,可在线阅读,更多相关《《APUE》读书笔记—第十三章守护进程(9页珍藏版)》请在金锄头文库上搜索。

1、APUE读书笔记第十三章守护进程守护进程也称为精灵进程是一种生存期较长的一种进程。它们独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件。他们常常在系统引导装入时启动,在系统关闭时终止。unix 系统有很多守护进程,大多数服务器都是用守护进程实现的,例如 inetd守护进程。1、守护进程的特征用 ps 命令察看一些常用的系统守护进程,看一下他们和几个概念:进程组、控制终端和会话有什么联系。执行: ps axj ,结果如下所示:从结果可以看出守护进程没有控制终端,其终端名设置为?,终端前台进程组 ID 设置为-1,init 进程 ID 为 1。系统进程依赖于操作系统实现,父进程 ID

2、 为 0 的各进程通常是内核进程,它们作为系统自举的一部分而启动。内核进程以超级用户特权运行,无控制终端,无命令行。大多数守护进程的父进程是 init 进程。守护进程与后台进程的区别:(1) 后台运行程序,即加启动的程序,(2)后台运行的程序拥有控制终端,守护进程没有。2、守护进程编程规则(1)调用 umask 将文件模式创建屏蔽字设置 为 0。因为进程从创建它的父进程那里继承了文件创建掩模。它可能修改守护进程所创建的文件的存取位。为防止这一点,将文件创建掩模清除:调用 umask(0)。(2)调用 fork,然后使父进程退出。这样可避免挂起控制终端将 Daemon 放入后台执行。(3)调用

3、setsid 以创建一个新会话。这样可以使得调用进程成为新会话的首进程,成为一个新进程组的组长进程,没有控制终端。(4)将当前工作目录更改为根目录。进程活动时,其工作目录所在的文件系统不能卸下。一般需要将工作目录改变到根目录。对于需要转储核心,写运行日志的进程将工作目录改变到特定目录如/tmpchdir(/) 。(5)关闭不再需要的文件描述符。进程从父进程那里继承了打开的文件描述符。如不关闭,将会浪费系统资源,造成进程所在的文件系统无法卸下以及引起无法预料的错误。(6)某些守护进程打开/dev/null 使其具有文件描述符 0、1 和 2。使得任何一个试图读标准输入、写标准输出或者标准出错的历

4、程都不会产生任何效果。(7)处理 SIGCHLD 信号 。处理 SIGCHLD 信号并不是必须的。但对于某些进程,特别是服务器进程往往在请求到来时生成子进程处理请求。如果父进程不等待子进程结束,子进程将成为僵尸进程(zombie)从而占用系统资源。如果父进程等待子进程结束,将增加父进程的负担,影响服务器进程的并发性能。在 Linux 下可以简单地将 SIGCHLD 信号的操作设为 SIG_IGN。初始化一个守护进程的程序如下:#include #include #include #include #include #include #include #include #include void

5、 daemonize(const char *cmd)int i,fd0,fd1,fd2;pid_t pid;struct rlimit r1;struct sigaction sa;umask(0);/获取文件描述符最大值getrlimit(RLIMIT_NOFILE,&r1);/创建子进程if(pid = fork() 0) /使父进程退出exit(0);setsid(); /创建会话 /创建子进程避免获取终端sa.sa_handler = SIG_IGN;sigemptyset(&sa.sa_mask);sa.sa_flags = 0;sigaction(SIGHUP,&sa,NULL)

6、;if(pid = fork() 0)exit(0);/修改目录chdir(/);/关闭不需要的文件描述符if(r1.rlim_max = RLIM_INFINITY)r1.rlim_max = 1024;for(i=0;i void openlog(const char *ident, int option, int facility);void syslog(int priority, const char *format, .);void closelog(void); int setlogmask(int mask);#include void vsyslog(int priority

7、, const char *format, va_list ap);大多数 syslog 实现将使消息多时间处于队列中,如果在此时间中到达了重复消息,那么syslog 守护进程将不把它写到日志记录中,而是打印输出重复消息。4、单实例守护进程为了正常运作,某些守护进程实现为单实例,即在任一时刻只运行该守护进程的一个副本。采用文件锁和记录锁机制可以实现单实例守护进程,如果每一个守护进程创建一个文件,并且在整个文件上加上一把锁,那就只允许创建一把这样的写锁,之后试图再创建这样的一把写锁将会失败。这样就保证守护进程只有一个副本在运行。使用文件和记录锁保证只运行某守护进程的一个副本,守护进程的每个副本都

8、试图创建一个文件,并将其进程 ID 写到该文件中。程序如下:#include #include #include #include #include #include #include #include #include #define LOCKFILE /var/run/daemon.pid#define LOCKMODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH )extern int lockfile(int);int already_running(void)int fd;char buf16;/打开文件,不存在则创建fd = open(LOCKFI

9、LE,O-RDWR|O_CREAT,LOCKMODE);if(fd #include #include #include #include #include #include #include #include #include #define LOCKFILE /var/run/daemon.pid#define LOCKMODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH )sigset_t mask;int lockfile(int fd)struct flock f1;f1.l_type = F_WRLCK;f1.l_start = 0;f1.l_wh

10、ence = SEEK_SET;f1.l_len = 0;return fcntl(fd,F_SETLK,&f1);int already_running(void)int fd;char buf16;fd = open(LOCKFILE,O_RDWR|O_CREAT,LOCKMODE);if(fd 0)exit(0);setsid();sa.sa_handler = SIG_IGN;sigemptyset(&sa.sa_mask);sa.sa_flags = 0;sigaction(SIGHUP,&sa,NULL);if(pid = fork() 0)exit(0);chdir(/);if(

11、r1.rlim_max = RLIM_INFINITY)r1.rlim_max = 1024;for(i=0;ir1.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);void reread()printf(read

12、daemon config file again.n);void * thread_func(void *arg)int err,signo;while(1)sigwait(&mask,&signo);switch(signo)case SIGHUP:syslog(LOG_INFO,Re-reading configuration file.n);reread();break;case SIGTERM:syslog(LOG_INFO,got SIGTERM;exiting.n);exit(0);default:syslog(LOG_INFO,unexpected signal %d.n,sig

13、no);return NULL;int main(int argc,char *argv)pthread_t tid;char *cmd;struct sigaction sa;if(cmd = strrchr(argv0,/) = NULL)cmd = argv0;elsecmd+;daemonize(cmd);if(already_running()syslog(LOG_ERR,daemon already running.n);exit(1);sa.sa_handler =SIG_DFL;sigemptyset(&sa.sa_mask);sa.sa_flags = 0;sigaction(SIGHUP,&sa,NULL);sigfillset(&mask); pthread_sigmask(SIG_BLOCK,&mask,NULL);pthread_create(&tid,NULL,thread_func,0);sleep(90);exit(0);关于本章介绍的守护进程,很多地方不是很懂,具体怎么应用还不清楚,先了解个大概,知道什么是守护进程及其作用。具体怎么用日后再来补充,有待加强。

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 行业资料 > 其它行业文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号