本文介绍一个例程daemon_init()

#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
#include <syslog.h>
#define MAXFD 64
void daemon_init(const char *pname, int facility)
{
int i:
pid_t pid;
/* fork,终止父进程 */
if (pid = fork())
exit(0);
/* 第一子进程 */
setsid();
signal(SIGHUP,SIG_IGN);
/* fork,终止第一子进程 */
if (pid = fork())
exit(0);
/* 第二子进程 */
daemon_proc = 1;
/* 将工作目录设定为"/" */
chdir("/");
/* 清除文件掩码 */
umask(0);
/* 关闭所有文件句柄 */
for (i = 0;i < MAXFD;i++)
{
close(i);
}
/* 打开log */
openlog(pname,LOG_PID,facility);
}

  守护进程建立的主要过程

1、fork

通过fork出一个子进程,并把父进程关闭,这样子进程就成了后台进程,而且子进程从父进程那里继承了组标识符同时又拥有了自己的进程标识符,这样就保证了子进程不会是一个进程组的首进程

2、setsid

setsid()创建了一个新的进程组,调用进程成为了这个进程组的首进程,这样就使得该进程脱离了原来的终端,成为了独立于终端外的进程

3、忽略SIGHUP信号,重新fork

这样使进程不再是进程组的首进程,可以放置在某些情况下的打开终端而重新与终端发生联系

4、改变工作目录,清除文件掩码

改变目录是为了切断进程与原有文件系统的联系,并且保证无论从什么地方启动进程都能正常工作,清除文件掩码是为了消除进程自身对其创建文件的影响

5、关闭全部已经打开的文件jubing

防止子进程继承了父进程中打开的文件而使这些文件始终保持打开状态从而产生某些冲突

6、打开log系统

个人对这个例子的理解就是,首先该进程是一个父进程,拥有进程组标识符和进程标识符,然后通过fork创建一个子进程(第一子进程),终止父进程,但是呢,子进程虽然拥有自己的进程标识符,但却继承了父进程的进程组(进程组一)标识符,所以,该进程组是原先就存在的,那么这个第一子进程就不是该进程组的首进程了。然后呢,通过setsid创建了一个新的进程组(进程组二),因为是新创建的,所以必然是首进程咯,那么这个首进程就脱离了原先的进程环境,独立于终端外了,然后呢,在这个新的进程组(进程组二)又重新fork出一个子进程(第二子进程),对于第二子进程来说,第一子进程就是其父进程,所以将父进程终止就是将第一子进程终止,此时,第二子进程已经独立于原来的终端外了,并且该第二子进程也不是所属进程组(进程组二)的首进程,最后改变工作目录,清掩码,关闭文件句柄,打开Log系统,那么这个第二子进程就是创建的守护进程,嗯,我是这么理解的,不知道理解对不对?请大神指出!

Linux网络编程学习(四) -----守护进程的建立(第三章)的更多相关文章

  1. Linux网络编程学习计划

    由于网络编程是很重要的一块,自己这一块也比较欠缺,只知道一些皮毛,从今天开始系统学习<Linux网络编程>一书,全书分为十四个章节: 第一章   概论   P1-16 第二章   UNIX ...

  2. Linux网络编程学习路线

    转载自:https://blog.csdn.net/lianghe_work/article 一.网络应用层编程   1.Linux网络编程01——网络协议入门 2.Linux网络编程02——无连接和 ...

  3. Linux网络编程学习(二) ----- 进程控制(第三章)

    1.进程和程序 程序是一个可执行文件,而一个进程是一个执行中的程序实例.一个进程对应于一个程序的执行,进程是动态的,程序是静态的,多个进程可以并发执行同一个程序.比如几个用户可以同时运行一个编辑程序, ...

  4. Unix环境高级编程(十四)守护进程实现时间服务器

    守护进程是在后台运行不受终端控制的进程(如输入.输出等),一般的网络服务都是以守护进程的方式运行.守护进程脱离终端的主要原因有两点:(1)用来启动守护进程的终端在启动守护进程之后,需要执行其他任务.( ...

  5. Linux网络编程学习(一) ----- 概论和Linux模型(第一章第二章)

    1.什么是计算机网络,通信方式是什么? 计算机网络就是通过通信线路相互连接的计算机的集合,主要通过双绞线.同轴电缆.电话线或者光缆等有形传输介质通信,还有就是通过激光.微波.卫星等实现无线通信 2.W ...

  6. Linux网络编程学习(九) ----- 消息队列(第四章)

    1.System V IPC System V中引入的几种新的进程间通信方式,消息队列,信号量和共享内存,统称为System V IPC,其具体实例在内核中是以对象的形式出现的,称为IPC 对象,每个 ...

  7. Linux网络编程学习(七) ----- 有名管道(第四章)

    1.什么是有名管道?为什么有了管道还需要有名管道? 有名管道是解决管道不能提供非父子进程间通信的缺陷.管道在Linux系统内部是以文件节点(inode)的形式存在,但由于其对外的不可见性(“无名”性) ...

  8. Linux网络编程学习(五) ----- 信号(第四章)

    1.基本概念 进程阻塞: 进程执行条件得不到满足,就自动放弃CPU资源而进入休眠状态,以等待条件满足,当条件满足时,系统就将控制权还给该进程进行未完成的操作 共享资源: 进程间协调使用的系统资源 锁定 ...

  9. Linux网络编程学习(八) ----- 文件和记录锁定(第四章)

    1.什么是文件和记录锁定? 文件锁定的是整个文件,而记录锁定只锁定文件的一部分,文件和记录锁分为咨询式锁定和强制锁定 1)咨询式锁定 某个进程对某个文件进行了咨询式锁定,其他想访问该文件的进程将会被操 ...

随机推荐

  1. 使用pip命令自动生成项目安装依赖清单

    Python项目中经常会带requirements.txt文件,里面是项目所依赖的包的列表,也就是依赖关系清单,这个清单也可以使用pip命令自动生成. pip命令: 1 pip freeze > ...

  2. iOS tableView分割线高度自定义

    1.系统自带的集中分割线的形式 myTableView.separatorStyle=UITableViewCellSeparatorStyleNone;(这个是去掉所有分割线)可以通过这个来设置 2 ...

  3. 关于multi-index

    [转载请注明出处]http://www.cnblogs.com/mashiqi 2017/02/22 将$D^{\alpha}$和$\partial^{\alpha}$区别对待.$D^{\alpha} ...

  4. Python全栈之路----常用模块----datetime模块详解

    相比于time模块,datetime模块的接口则更直观,更容易调用. datetime模块定义了下面这几个类: datetime.date:表示日期的类,常用的属性有year,month,day: d ...

  5. 关于c风格的字符串的基本函数

    1.两个字符串的比较 //如果两个字符串相等 strcmp(s1,s2)=; //如果s1>s2 strcmp(s1,s2)>; //如果s1<s2 strcmp(s1,s2)< ...

  6. 洛谷P1605:迷宫(DFS)

    题目背景 迷宫 [问题描述] 给定一个N*M方格的迷宫,迷宫里有T处障碍,障碍处不可通过.给定起点坐标和终点坐标,问: 每个方格最多经过1次,有多少种从起点坐标到终点坐标的方案.在迷宫中移动有上下左右 ...

  7. MySQL Execution Plan--IN查询计划

    对于IN查询,MySQL会根据当前表数据结构(索引)和数据分布(统计信息和预估)生成多种执行计划,并根据执行成本挑选出“最优执行计划”. 假设有查询 SELECT * FROM student ,,, ...

  8. JS笔记汇总

      注释必须要多写! 1.方便后台看 2.方便自己查错和优化 事先先沟通约定好,比如交互的数据格式需求是怎么样的啊,功能模块的逻辑是怎么样的等等.提前先和产品还有后台沟通好.   JSON内不能包含注 ...

  9. nodeppt:网页版 PPT

    资料 网址 github https://github.com/ksky521/nodeppt 网页版PPT(nodeppt 的介绍) http://deliazhi.com/2017/03/31/W ...

  10. Eclipse Build path

    Build Path用于设置Java的构建路径,管理Java工程所包含的资源,使工程结构清晰合理. 包括以下几项: Source Source包括 source folder和output folde ...