Intro

-----

守护进程,也就是通常说的Daemon进程,是Linux中的后台服务进程。它是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。守护进程常常在系统引导装入时启动,在系统关闭时终止。Linux系统有很多守护进程,大多数服务都是通过守护进程实现的,同时,守护进程还能完成许多系统任务,例如,作业规划进程crond、打印进程lqd等(这里的结尾字母d就是Daemon的意思)。

由于在Linux中,每一个系统与用户进行交流的界面称为终端,每一个从此终端开始运行的进程都会依附于这个终端,这个终端就称为这些进程的控制终端,当控制终端被关闭时,相应的进程都会自动关闭。但是守护进程却能够突破这种限制,它从被执行开始运转,直到整个系统关闭时才退出。如果想让某个进程不因为用户或终端或其他地变化而受到影响,那么就必须把这个进程变成一个守护进程,下面将完整代码贴上。

 /************************************************
* 该例程讲解Linux守护进程的编程方法
************************************************/
#include <unistd.h>
#include <signal.h>
#include <sys/param.h> // NOFILE
#include <sys/stat.h> // umask
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <assert.h> bool initDaemon()
{
// 屏蔽一些有关控制终端操作的信号
// 防止守护进程没有正常运转起来时,因控制终端受到干扰退出或挂起
assert(signal(SIGINT, SIG_IGN) != SIG_ERR); // 终端中断
assert(signal(SIGHUP, SIG_IGN) != SIG_ERR); // 连接挂断
assert(signal(SIGQUIT, SIG_IGN) != SIG_ERR);// 终端退出
assert(signal(SIGPIPE, SIG_IGN) != SIG_ERR);// 向无读进程的管道写数据
assert(signal(SIGTTOU, SIG_IGN) != SIG_ERR);// 后台程序尝试写操作
assert(signal(SIGTTIN, SIG_IGN) != SIG_ERR);// 后台程序尝试读操作
assert(signal(SIGTERM, SIG_IGN) != SIG_ERR);// 终止 // [1] 创建一个子进程,父进程退出
int pid = fork();
if (pid)
{
// 父进程退出
exit();
}
else if (pid < )
{
return false;
} // 子进程继续运行 // [2] 在子进程中创建新的会话,setsid有三个作用
// a.让进程摆脱原会话的控制
// b.让进程摆脱原进程组的控制
// c.让进程摆脱原控制终端的控制
int ret = setsid();
if (ret < )
{
return false;
} // [3] 禁止进程重新打开控制终端
// 进程已经成为无终端的会话组长,但它可以重新申请打开一个控制终端
// 可以通过使进程不再成为会话组长来禁止进程重新打开控制终端
pid = fork();
if (pid)
{
// 结束第一个子进程
exit();
}
else if (pid < )
{
return false;
} // 第二个子进程继续运行 // [4] 关闭打开的文件描述符
// 进程从创建它的父进程那里继承了打开的文件描述符,如果不关闭,将会浪费系统资源,
// 造成进程所在的文件系统无法卸下以及引起无法预料的错误
for (int i = ; i < NOFILE; ++i)
{
close(i);
} // [5] 改变当前工作目录
// 进程活动时,其工作目录所在的文件系统不能卸下,一般将工作目录改变到根目录
ret = chdir("/");
if (ret < )
{
return false;
} // [6] 重新设置文件创建掩码
// 进程从创建它的父进程那里继承了文件创建掩码,它可能修改守护进程所创建的文件的存取位
// 所以将文件创建掩码清除
umask(); return true;
} int main()
{
// 初始化守护进程
bool ret = initDaemon();
if (!ret)
{
printf("Init daemon failed\n");
return ;
} FILE* file = NULL;
time_t t = ; // 每隔10秒向test.log报告运行状态
while (true)
{
sleep();
file = fopen("./var/test.log", "a+");
if (file != NULL)
{
t = time(NULL);
fprintf(file, "I am here at %s\n", asctime(localtime(&t)));
fclose(file);
}
} return ;
}

该例子的github地址:https://github.com/chxuan/samples/blob/master/Daemon/Daemon.cpp

Linux编程之《守护进程》的更多相关文章

  1. Linux编程之《看门狗进程》

    Intro 当我们编写服务器代码时,为了让自己的服务器在意外崩溃时能够及时的重启,软件看门狗就显示出它的作用了,该看门狗进程是通过fork一个子进程(业务进程),父进程一旦捕获到了子进程的结束信号就重 ...

  2. Linux编程 7 (实时监测进程 top, 结束进程kill,killall)

    一. 实时监测进程 top 在一篇里讲到ps命令在收集进程信息时非常有用,但它只能显示某个特定时间点的信息.想要观察那些频繁换进换出的内存进程趋势,用top命令是合适的.使用top命令如下图所示: 在 ...

  3. 10.3、android输入系统_必备Linux编程知识_任意进程双向通信(scoketpair+binder)

    3. 任意进程间通信(socketpair_binder) 进程每执行一次open打开文件,都会在内核中有一个file结构体表示它: 对每一个进程在内核中都会有一个task_struct表示进程,这个 ...

  4. Linux 下如何使用看门狗

      Linux内核有集成WD的选项.将其使能后,系统里就会有watchdog的设备驱动:/dev/watchdog.这样,在应用程序里只需打开这个设备使用即可:#include <fcntl.h ...

  5. Linux 软件看门狗 watchdog 喂狗

    Linux 自带了一个 watchdog 的实现,用于监视系统的运行,包括一个内核 watchdog module 和一个用户空间的 watchdog程序.内核 watchdog 模块通过 /dev/ ...

  6. 【目录】linux 编程

    随笔分类 - linux 编程 Linux编程 24 shell编程(结构化 if [ condition ] 数值比较,字符串比较) 摘要: 一.概述 接着上篇讲的结构化命令,最后讲到了test命令 ...

  7. linux设备驱动归纳总结(十一):写个简单的看门狗驱动【转】

    本文转载自:http://blog.chinaunix.net/uid-25014876-id-112879.html linux设备驱动归纳总结(十一):写个简单的看门狗驱动 xxxxxxxxxxx ...

  8. linux内核中断之看门狗

    一:内核中断 linux内核中的看门狗中断跟之前的裸板的中断差不多,在编写驱动之前,需要线把内核自带的watch dog模块裁剪掉,要不然会出现错误:在Device Drivers /Watchdog ...

  9. Linux C语言编程学习笔记 (1)进程控制入门

    想进行Linux系统开发已经很久了,一直没有付诸实践.今日终于开始学习Linux下的C语言编程,研究一天,终于大概弄明白了Linux系统进程管理的一些基本概念和编程方法,总结下来以方便大家学习和自己实 ...

随机推荐

  1. 关于在Eclipse里面启动了服务,但是localhost:8080无法访问的问题:

    今天eclipse重新换了一个然后写项目,结果发生了一些bug,当在Tomca服务开启之后,浏览器端输入localhost:8080无法访问,以为是服务器没有搞定,检查了没问题,百度了一下有很多乱七八 ...

  2. bzoj 1537 [POI2005]Aut- The Bus(DP+BIT)

    [题意] 顺序经过k个点,求获得的最大权值和. [思路] 设f[i]表示到第i个点,则有转移式: f[i]=min{ f[j]+w[i] } x[j]<=x[i],y[j]<=y[i] 满 ...

  3. 圆内,求离圆心最远的整数点 hiho一下第111周 Farthest Point

    // 圆内,求离圆心最远的整数点 hiho一下第111周 Farthest Point // 思路:直接暴力绝对T // 先确定x范围,每个x范围内,离圆心最远的点一定是y轴两端的点.枚举x的范围,再 ...

  4. [转]JQuery.Ajax之错误调试帮助信息

    下面是Jquery中AJAX参数详细列表: 参数名 类型 描述 url String (默认: 当前页地址) 发送请求的地址. type String (默认: "GET") 请求 ...

  5. EasyMock

    使用 EasyMock 更轻松地进行测试 窥探EasyMock(1)基础使用篇 窥探EasyMock(2)进阶使用篇

  6. Can’t find file mysql/host.frm

    安装Mysql后报错: InnoDB: Apply batch completed 141115 15:04:36 InnoDB: Started; log sequence number 0 442 ...

  7. JAVA虚拟机之类加载器

    转载请声明:原文转自http://www.cnblogs.com/xiezie/p/5909570.html 1.JVM的生命周期 1.1 JVM的生命周期和程序的生命周期一致 1.2 JVM结束生命 ...

  8. Uva 208 - Firetruck

    [题目链接]http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&p ...

  9. 激活Windows 10

    激活Windows 10按 win+X 组合键,打开“命令提示符(管理员)”,输入以下代码:slmgr /ipk NKJFK-GPHP7-G8C3J-P6JXR-HQRJR  然后按Enter键回车即 ...

  10. JavaSE聊天室

    今天学习了一下简单聊天程序(类似QQ那种)的编写过程,从最初的0.1版本到最后的1.3版本,功能不断地增强,下面对一天的学习内容进行梳理. 版本0.1 我们的需求是显示一个窗体,其他什么也不用做,其他 ...