守护进程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章 守护进程的更多相关文章

  1. UNIX环境高级编程——单实例的守护进程

    #include <stdio.h> #include <stdlib.h> #include <string.h> #include <signal.h&g ...

  2. UNIX环境高级编程 第5章 标准I/O库

    本章是关于C语言标准I/O库的,之所以在UNIX类系统的编程中会介绍C语言标准库,主要是因为UNIX和C之间具有密不可分的关系.由于UNIX系统存在很多实现,而每个实现都有自己的标准I/O库,为了统一 ...

  3. unix环境高级编程第三章笔记

    文件描述符 1.文件描述符的概念 对于内核而言,所有打开的文件都会用一个文件描述符来引用,打开或和创建一个新文件的时候,内核会给进程返回一个文件描述符,而当使用read write时,可以使用这个文件 ...

  4. UNIX环境高级编程 第7章 进程环境

    本章涉及C/C++程序中main函数是如何被调用的.命令行参数如何传递给main函数.程序的内存空间布局.程序如何使用环境变量.程序如何终止退出. main函数 C程序或C++程序总是从main函数开 ...

  5. UNIX环境高级编程 第8章 进程控制

    本章是UNIX系统中进程控制原语,包括进程创建.执行新程序.进程终止,另外还会对进程的属性加以说明,包括进程ID.实际/有效用户ID. 进程标识 每个进程某一时刻在系统中都是独一无二的,它们之间是用一 ...

  6. UNIX环境高级编程 第9章 进程关系

    在第8章学习了进程的控制原语,通过各种进程原语可以对进程进行控制,包括新建进程.执行新程序.终止进程等.在使用fork( )产生新进程后,就出现了进程父子进程的概念,这是进程间的关系.本章更加详细地说 ...

  7. UNIX环境高级编程 第6章 系统数据文件和信息

    UNIX系统的正常运作需要用到大量与系统有关的数据文件,例如系统用户账号.用户密码.用户组等文件.出于历史原因,这些数据文件都是ASCII文本文件,并且使用标准I/O库函数来读取. 口令文件 /etc ...

  8. UNIX环境高级编程 第1章 UNIX基础知识

    所有操作系统都为运行在它之上的程序提供各种服务,典型的服务包括:执行新程序.打开文件.读写文件.分配存储空间.提供时间等. UNIX体系结构 严格来说,操作系统是一种软件,它控制计算机硬件资源,提供程 ...

  9. UNIX环境高级编程 第16章 网络IPC:套接字

    上一章(15章)中介绍了UNIX系统所提供的多种经典进程间通信机制(IPC):管道PIPE.命名管道FIFO.消息队列Message Queue.信号量Semaphore.共享内存Shared Mem ...

随机推荐

  1. Spyder & Python

    Spyder & Python https://pypi.org/project/spyder/ Spyder is a powerful scientific environment wri ...

  2. 二分图最大匹配模板(pascal)

    uoj#78. 二分图最大匹配 从前一个和谐的班级,有 nlnl 个是男生,有 nrnr 个是女生.编号分别为 1,…,nl1,…,nl 和 1,…,nr1,…,nr. 有若干个这样的条件:第 vv  ...

  3. 80X86计算机组织

    计算机主要由运算器.控制器.存储器.和输入输出设备构成. 主频: 主频是指芯片所用的主时钟频率,它直接影响计算机的运行速度,由于处理器体系结构的差别,同样的主频可能产生不同的计算速度,但主频仍然是反映 ...

  4. MySQL 大表备份、改表

    0.背景: 需要对一个千万行数据的表新增字段,具体操作: a.dump 数据 b.delete 数据 c.alter 表 MySQL  版本为5.5,alter表时MySQL会锁表:表行数虽多,当数据 ...

  5. P4101 [HEOI2014]人人尽说江南好

    题目描述 小 Z 是一个不折不扣的 ZRP(Zealot Round-game Player,回合制游戏狂热玩家),最近他 想起了小时候在江南玩过的一个游戏. 在过去,人们是要边玩游戏边填词的,比如这 ...

  6. c++11 标准库函数 std::move 和 完美转发 std::forward

    c++11 标准库函数 std::move 和 完美转发 std::forward #define _CRT_SECURE_NO_WARNINGS #include <iostream> ...

  7. [洛谷P3175][HAOI2015]按位或

    题目大意:刚开始有一个数$x=0$,每秒钟有一个数$y\in[0,2^n)(n\leqslant20)$按一定概率随机出现,数$i$的概率为$p_i$,保证$\sum\limits_{i=0}^{2^ ...

  8. 【2018ICPC沈阳】

    哈密顿距离转切比雪夫距离,多种颜色跟两种颜色没有区别,记录最大最小次大次小即可. 圆求交点.

  9. Unity使用C#实现简单Scoket连接及服务端与客户端通讯

    简介: 网络编程是个很有意思的事情,偶然翻出来很久之前刚开始看Socket的时候写的一个实例,贴出来吧 Unity中实现简单的Socket连接,c#中提供了丰富的API,直接上代码. 服务端代码: [ ...

  10. 【洛谷4005】小Y和地铁(搜索)

    [洛谷4005]小Y和地铁(搜索) 题面 洛谷 有点长. 题解 首先对于需要被链接的两个点,样例中间基本上把所有的情况都给出来了. 但是还缺了一种从下面绕道左边在从整个上面跨过去在从右边绕到下面来的情 ...