Linux网络编程学习(四) -----守护进程的建立(第三章)
本文介绍一个例程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网络编程学习(四) -----守护进程的建立(第三章)的更多相关文章
- Linux网络编程学习计划
由于网络编程是很重要的一块,自己这一块也比较欠缺,只知道一些皮毛,从今天开始系统学习<Linux网络编程>一书,全书分为十四个章节: 第一章 概论 P1-16 第二章 UNIX ...
- Linux网络编程学习路线
转载自:https://blog.csdn.net/lianghe_work/article 一.网络应用层编程 1.Linux网络编程01——网络协议入门 2.Linux网络编程02——无连接和 ...
- Linux网络编程学习(二) ----- 进程控制(第三章)
1.进程和程序 程序是一个可执行文件,而一个进程是一个执行中的程序实例.一个进程对应于一个程序的执行,进程是动态的,程序是静态的,多个进程可以并发执行同一个程序.比如几个用户可以同时运行一个编辑程序, ...
- Unix环境高级编程(十四)守护进程实现时间服务器
守护进程是在后台运行不受终端控制的进程(如输入.输出等),一般的网络服务都是以守护进程的方式运行.守护进程脱离终端的主要原因有两点:(1)用来启动守护进程的终端在启动守护进程之后,需要执行其他任务.( ...
- Linux网络编程学习(一) ----- 概论和Linux模型(第一章第二章)
1.什么是计算机网络,通信方式是什么? 计算机网络就是通过通信线路相互连接的计算机的集合,主要通过双绞线.同轴电缆.电话线或者光缆等有形传输介质通信,还有就是通过激光.微波.卫星等实现无线通信 2.W ...
- Linux网络编程学习(九) ----- 消息队列(第四章)
1.System V IPC System V中引入的几种新的进程间通信方式,消息队列,信号量和共享内存,统称为System V IPC,其具体实例在内核中是以对象的形式出现的,称为IPC 对象,每个 ...
- Linux网络编程学习(七) ----- 有名管道(第四章)
1.什么是有名管道?为什么有了管道还需要有名管道? 有名管道是解决管道不能提供非父子进程间通信的缺陷.管道在Linux系统内部是以文件节点(inode)的形式存在,但由于其对外的不可见性(“无名”性) ...
- Linux网络编程学习(五) ----- 信号(第四章)
1.基本概念 进程阻塞: 进程执行条件得不到满足,就自动放弃CPU资源而进入休眠状态,以等待条件满足,当条件满足时,系统就将控制权还给该进程进行未完成的操作 共享资源: 进程间协调使用的系统资源 锁定 ...
- Linux网络编程学习(八) ----- 文件和记录锁定(第四章)
1.什么是文件和记录锁定? 文件锁定的是整个文件,而记录锁定只锁定文件的一部分,文件和记录锁分为咨询式锁定和强制锁定 1)咨询式锁定 某个进程对某个文件进行了咨询式锁定,其他想访问该文件的进程将会被操 ...
随机推荐
- 根据ip获取地理信息
function getIPLoc_sina($queryIP){ $url = 'http://int.dpool.sina.com.cn/iplookup/iplookup.php?form ...
- rootfs 制作
最小 根文件系统 (1)/dev/console(终端控制台, 提供标准输入.标准输出以及标准错误) /dev/null (表示空设备终端, 所有写到这个文件中的数据都会被丢弃掉.) (2)init进 ...
- IDEA java编译中出现了Exception in thread “main" java.lang.UnsupportedClassVersionError
这个问题确实是由较高版本的JDK编译的java class文件试图在较低版本的JVM上运行产生的错误. 在idea中需要修改的有两区,四个地方 1. 修改项目编译器 Crtl+Shift+A 进入如下 ...
- 在vue中使用Echarts画曲线图(异步加载数据)
现实的工作中, 数据不可能写死的,所有的数据都应该通过发送请求进行获取. 所以本项目的需求是请求服务器获得二维数组,并生成曲线图.曲线图的横纵坐标均从获得的数据中取得. Echarts官方文档: ht ...
- Arcgis Server 本地化
一.将API包放入server文件夹 将3.18的arcgis API 解压放入Arcgis Server的安装目录的……\Server\framework\runtime\tomcat\webapp ...
- XXS level8
(1)查看PHP源代码 <?php ini_set("display_errors", 0); $str = strtolower($_GET["keyword&q ...
- mysql建表规范及注意事项
表设计规范 1.库名,表名,字段名必须使用小写字母,“-”分割 ,长度不得超过12字符 , 要见名识意 : 2.建议使用Innodb存储引擎 (1)什么是存储引擎 不同的技术及配套的相关功能就是存储引 ...
- python gevent自动挡的协程切换。
import gevent def func(): print('running func 111')#第一步运行 gevent.sleep(2)#切换到下个协程 print('running fun ...
- 深入学习Motan系列(三)——服务发布
袋鼠回头看了看文章,有些啰嗦,争取语音简练,不断提高表达力!袋鼠奋起直追! 注:此篇文章,暂时为了以后时间线排序的需要,暂时发表出来,可是仍然有许多地方需要改写.自己打算把服务端发布,客户端订阅都搞定 ...
- 关于windows下的文件结束符
在<c++ primer>中有说,在windows中文件结束符为:ctrl+z,在Linux中为:ctrl+D. 但是在while(cin>>s)的语句运行中,需要两次的^Z, ...