UNIX环境高级编程 第13章 守护进程
守护进程daemon是一种生存周期很长的进程。它们通常在系统引导时启动,在系统关闭时终止。守护进程是没有终端的,它们一直在后台运行。
守护进程的特征
在Linux系统中,可以通过命令 ps -efj 来查看守护进程。例如下图:
从上图中可以看到 TTY 一列,该列显示每个进程的终端,对于问号(?)显示的进程,表明该进程没有控制终端。而CMD列中方括号[ ]显示的进程表明这是一个内核守护进程,对于用户守护进程则没有方括号[ ]。
编程规则
如果需要编写进程守护程序,则需要遵循一些基本规则,具体如下:
- 1. 调用umask将文件模式创建屏蔽字设置为一个指定值。因为守护进程如果要创建文件,那么该文件必须指定权限,确保文件权限是自己期望的。
- 2. 调用fork,然后使父进程exit,这是使得守护进程不关联终端的前提条件。另外,如果守护进程从终端命令行启动,那么父进程exit会使得shell认为该命令执行完毕从而正常返回。
- 3. 调用setsid创建新会话,并丢掉控制终端。
- 4. 将进程当前工作目录更改为根目录,因为进程可能启用于一个临时挂载的目录,如果进程一直执行,那么挂载目录就无法卸载。
- 5.关闭不再需要的文件描述符,主要防止守护进程误写。
- 6. 打开/dev/null 文件,使得进程具有文件描述符0,1,2,这样做是为了预防守护进程调用的第三方接口或者库组件尝试从标准输入输出读写。
以上6点基本上是编写一个守护进程所必须的,也就是说,如果要编写一个严谨的守护进程,那么最好将上述步骤全部囊括。
出错记录
守护进程需要处理的一个问题是如何处理出错问题,因为守护进程没有控制终端,所以它无法进行标准错误输出,另外也不能简单地直接将出错信息写入到一个日志文件中,因为对管理人员而言,他不可能去统计记住系统中所有进程对应的出错记录日志文件(目录及其文件名)。因此需要有一个集中的出错记录管理守护进程来专门统一负责出错记录。
对于内核守护进程,可以通过调用log( )函数来向出错日志统计守护进程发送消息,但我们不会编写内核级守护进程。
对于用户守护进程,可以通过调用syslog( )函数来向出错日志统计守护进程发送消息,我们还可以同网络编程来向远程主机守护进程发送消息,对于网络编程本书并不涉及。对于syslog( )函数,其头文件及函数原型如下:
#include <syslog.h> void openlog (const char* ident, int option, int facility);
void syslog (int pri, const char* fmt, ...);
void closelog (void);
int setlogmask (int mask);
对于setlogmask( )函数返回之前日志记录优先级屏蔽字。
单示例守护进程
有些程序由于实际需要,在任一时刻系统中只能运行一个守护进程,例如守护进程要排他性的独占一个设备。典型的,对于cron进程而言,如果同时有多个示例运行,那么可能导致定时重复执行从而造成问题。为了实现单实例守护进程,可以利用UNIX系统的文件和记录锁功能来实现互斥。文件和记录锁功能是下一章的内容,在这里只需要知道,经过UNIX系统的支持,利用文件和记录锁功能能实现单实例守护进程,其原理是对文件写进行加锁,一次只能加一把写性质的锁,第二个守护进程试图加写锁时会报错,这样就实现了单实例进程。
守护进程的惯例
在UNIX系统中创建守护进程通常会遵循以下惯例:
如果守护进程是单实例的,且守护进程使用锁文件,那么该锁文件通常在 /var/run 目录下,并且守护进程创建的锁文件名字是name.pid形式,其中name替换为具体守护进程的名字。
如果守护进程支持配置选项,那么配置文件通常放在 /etc 目录下,并且配置文件名为name.conf,其中name替换为具体守护进程的名字。
如果守护进程意外终止,应该自动重新启动,在Ubuntu系统中,可以通过upstart来实现。
如果守护进程读取配置文件,那么守护进程会在启动时读取该文件,但在之后如果有人重新配置了文件,那么守护进程应该重新读取,为了重新读取配置文件,守护进程应该使用SIGHUP信号作为触发条件,因为守护终端不会有终端,因此永远不会用到SIGHUP信号,从而我们可以利用SIGHUP信号来告知守护进程重新读取配置文件,而不用担心信号误用。
UNIX环境高级编程 第13章 守护进程的更多相关文章
- UNIX环境高级编程——单实例的守护进程
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <signal.h&g ...
- UNIX环境高级编程 第5章 标准I/O库
本章是关于C语言标准I/O库的,之所以在UNIX类系统的编程中会介绍C语言标准库,主要是因为UNIX和C之间具有密不可分的关系.由于UNIX系统存在很多实现,而每个实现都有自己的标准I/O库,为了统一 ...
- unix环境高级编程第三章笔记
文件描述符 1.文件描述符的概念 对于内核而言,所有打开的文件都会用一个文件描述符来引用,打开或和创建一个新文件的时候,内核会给进程返回一个文件描述符,而当使用read write时,可以使用这个文件 ...
- UNIX环境高级编程 第7章 进程环境
本章涉及C/C++程序中main函数是如何被调用的.命令行参数如何传递给main函数.程序的内存空间布局.程序如何使用环境变量.程序如何终止退出. main函数 C程序或C++程序总是从main函数开 ...
- UNIX环境高级编程 第8章 进程控制
本章是UNIX系统中进程控制原语,包括进程创建.执行新程序.进程终止,另外还会对进程的属性加以说明,包括进程ID.实际/有效用户ID. 进程标识 每个进程某一时刻在系统中都是独一无二的,它们之间是用一 ...
- UNIX环境高级编程 第9章 进程关系
在第8章学习了进程的控制原语,通过各种进程原语可以对进程进行控制,包括新建进程.执行新程序.终止进程等.在使用fork( )产生新进程后,就出现了进程父子进程的概念,这是进程间的关系.本章更加详细地说 ...
- UNIX环境高级编程 第6章 系统数据文件和信息
UNIX系统的正常运作需要用到大量与系统有关的数据文件,例如系统用户账号.用户密码.用户组等文件.出于历史原因,这些数据文件都是ASCII文本文件,并且使用标准I/O库函数来读取. 口令文件 /etc ...
- UNIX环境高级编程 第1章 UNIX基础知识
所有操作系统都为运行在它之上的程序提供各种服务,典型的服务包括:执行新程序.打开文件.读写文件.分配存储空间.提供时间等. UNIX体系结构 严格来说,操作系统是一种软件,它控制计算机硬件资源,提供程 ...
- UNIX环境高级编程 第16章 网络IPC:套接字
上一章(15章)中介绍了UNIX系统所提供的多种经典进程间通信机制(IPC):管道PIPE.命名管道FIFO.消息队列Message Queue.信号量Semaphore.共享内存Shared Mem ...
随机推荐
- maven执行"mvn clean package" 命令报错
昨天利用mvn打包,执行程序'mvn clean package' 命令,发现打包失败 问题描述 具体看代码 发信tomcat下的log 清除不掉.为什么呢?忽然想起来我的项目服务还起着,于是我把服务 ...
- 【Java线程】SwingWorker的用法
Swing应用程序员常见的错误是误用Swing事件调度线程(Event DispatchThread,EDT).他们要么从非UI线程访问UI组件:要么不考虑事件执行顺序:要么不使用独立任务线程而在ED ...
- 用ClientDataSet更新数据表,怎样自动生成行号? [问题点数:40分]
ClientDataSet.First;while not ClientDataSet.eof dobegin ClientDataSet.edit; ClientDataSet.FieldByN ...
- SPOJ_LCS2
和上个题目差不多,这次是找若干个串的LCS,若干<=10 . 做法上面也是类似的. 首先以第一个建立SAM,然后后面的串都在上面更新.每个串的更新是独立进行的,互不影响.对于同一状态,首先在同一 ...
- springmvc+mybatis 处理时间
项目结构: 一.数据库中time的字段为datetime1. 数据库设计如图 2. addNews.jsp <%@ page language="java" contentT ...
- P3216 [HNOI2011]数学作业
题目描述 小 C 数学成绩优异,于是老师给小 C 留了一道非常难的数学作业题: 给定正整数 N 和 M ,要求计算Concatenate (1 .. N) Mod M 的值,其中 Concatenat ...
- 红黑树 Java实现
概要 前面分别介绍红黑树的理论知识.红黑树的C语言和C++的实现.本章介绍红黑树的Java实现,若读者对红黑树的理论知识不熟悉,建立先学习红黑树的理论知识,再来学习本章.还是那句老话,红黑树的C/C+ ...
- jdbc的封装(使用参数文件)
借鉴原CSDN作者yanzi1225627的一篇:http://blog.csdn.net/yanzi1225627/article/details/26950615 作者东西写的很好,自己用的时候进 ...
- 【刷题】LOJ 2480 「CEOI2017」One-Way Streets
题目描述 给定一张 \(n\) 个点 \(m\) 条边的无向图,现在想要把这张图定向. 有 \(p\) 个限制条件,每个条件形如 \((xi,yi)\) ,表示在新的有向图当中,\(x_i\) 要能够 ...
- 一个非典型的Linux路由配置方案
上周帮人解决了一个问题,这个问题绝对是非典型性的,采用了非常规的方法.虽然最终的方案非常不符合常规,非常不通用,充满了各种藏得很深的技巧或者说是trick,但是这个问题却是一个学习Linux路由的绝好 ...