Daemon——守护进程
创建守护进程
1. 创建子进程,父进程退出
2. 在子进程中创建新会话
- 进程组:是一个或多个进程的集合。进程组有进程组ID来唯一标识。除了进程号(PID)之外,进程组ID也是一个进程的必备属性。每个进程组都有一个组长进程,其组长进程的进程号等于进程组ID。且该进程组ID不会因组长进程的退出而受到影响。
- 会话周期:会话期是一个或多个进程组的集合。通常,一个会话开始于用户登录,终止于用户退出,在此期间该用户运行的所有进程都属于这个会话期。
setsid 函数的作用:
- setsid函数用于创建一个新的会话,并担任该会话组的组长。调用setsid有下面的3个作用:
- 让进程摆脱原会话的控制
- 让进程摆脱原进程组的控制
- 让进程摆脱原控制终端的控制
由于创建守护进程的第一步调用了fork函数来创建子进程,再将父进程退出。由于在调用了fork函数时,子进程全盘拷贝了父进程的会话期、进程组、控制终端等,虽然父进程退出了,但会话期、进程组、控制终端等并没有改变,因此,这还不是真正意义上的独立开来,而setsid函数能够使进程完全独立出来,从而摆脱其他进程的控制。
3. 改变当前目录为根目录
这一步也是必要的步骤。使用fork创建的子进程继承了父进程的当前工作目录。由于在进程运行中,当前目录所在的文件系统(如“/mnt/usb”)是不能卸载的,这对以后的使用会造成诸多的麻烦(比如系统由于某种原因要进入单用户模式)。因此,通常的做法是让"/"作为守护进程的当前工作目录,这样就可以避免上述的问题,当然,如有特殊需要,也可以把当前工作目录换成其他的路径,如/tmp。改变工作目录的常见函数式chdir。
4. 重设文件权限掩码
文件权限掩码是指屏蔽掉文件权限中的对应位。比如,有个文件权限掩码是050,它就屏蔽了文件组拥有者的可读与可执行权限。由于使用fork函数新建的子进程继承了父进程的文件权限掩码,这就给该子进程使用文件带来了诸多的麻烦。因此,把文件权限掩码设置为0,可以大大增强该守护进程的灵活性。设置文件权限掩码的函数是umask。在这里,通常的使用方法为umask(0)。
5. 关闭文件描述符
for( i = ; i < MAXFILE; i++)
close(i);
6. 守护进程退出处理
当用户需要外部停止守护进程运行时,往往会使用 kill命令停止该守护进程。所以,守护进程中需要编码来实现kill发出的signal信号处理,达到进程的正常退出。
signal(SIGTERM, sigterm_handler); void sigterm_handler(int arg)
{
_running = ;
}
fork() 两次:
写守护进程时,fork
两次并不是必须的。
在unix高级环境编程 第13章是这样解释的:
Under System V–based systems, some people recommend calling fork again at this point and having the parent terminate. The second child continues as the daemon. This guarantees that the daemon is not a session leader, which prevents it from acquiring a controlling terminal under the System V rules (Section 9.6). Alternatively, to avoid acquiring a controlling terminal, be sure to specify O_NOCTTY whenever opening a terminal device.
在基于System V的系统中, 有些人推荐再fork一次, 这些fork产生的进程就不再是session leader了, 避免打开控制终端。因为打开一个控制终端的前台条件是该进程必须是会话组长。再fork一次,子进程ID != sid(sid是进程父进程的sid)。所以也无法打开新的控制终端。
还有一种可选的方法,就是打开终端设备的时候指定O_NOCTTY来避免打开控制终端。
还有一种说法:
这里有一个假定,父进程生成守护进程后,还有自己的事要做。这样,如果父进程fork一次创建了一个守护进程,然后继续做其它事时阻塞了,这时守护进程一直在运行,父进程却没有正常退出。如果守护进程因为正常或非正常原因退出了,就会变成ZOMBIE进程。
如果fork两次,父进程先fork出一个儿子进程,儿子进程再fork出孙子进程做为守护进程,然后儿子进程立刻退出,守护进程被init进程接管,这样无论父进程做什么事,无论怎么被阻塞,都与守护进程无关了。所以,fork两次的守护进程很安全,避免了僵尸进程出现的可能性。
Daemon——守护进程的更多相关文章
- nohup命令、setsid命令、Daemon(守护进程)简要梳理
nohup命令 当用户注销(logout)或者网络断开时,终端会收到 HUP(hangup)信号从而关闭其所有子进程.因此,我们的解决办法就有两种途径:要么让进程忽略 HUP 信号,要么让进程运行在新 ...
- PHP7 网络编程(二)daemon守护进程
前言 在一个多任务的计算机操作系统中,守护进程(英语:daemon,/ˈdiːmən/或/ˈdeɪmən/)是一种在后台执行的计算机程序.此类程序会被以进程的形式初始化.守护进程程序的名称通常以字母“ ...
- python中的daemon守护进程实现方法
原文参考:http://blog.csdn.net/tao_627/article/details/49532021 守护进程是生存期长的一种进程.它们独立于控制终端并且周期性的执行某种任务或等待处理 ...
- linux下daemon守护进程的实现(以nginx代码为例)
ngx_int_t ngx_daemon(ngx_log_t *log) { int fd; // 让init进程成为新产生进程的父进程: // 调用fork函数创建子进程后,使父进程立即退出.这样, ...
- python网络编程--线程join和Daemon(守护进程)
一:什么情况下使用join join([timeout])调用join函数会使得主调线程阻塞,直到被调用线程运行结束或超时. 参数timeout是一个数值类型,用来表示超时时间,如果未提供该参数,那么 ...
- a daemon 守护进程
w Cron and Crontab usage and exampleshttps://www.pantz.org/software/cron/croninfo.html
- python学习笔记——守护进程
1 基本描述 守护进程:是系统中独立的后台服务进程, 特点:独立与终端并且周期性地执行某个任务,其生命周期长,一般随系统启动和终止. 缺点:进程的创建和销毁的时候需要消耗较多的计算机资源. 2 参考 ...
- linux系统编程之进程(八):守护进程详解及创建,daemon()使用
一,守护进程概述 Linux Daemon(守护进程)是运行在后台的一种特殊进程.它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件.它不需要用户输入就能运行而且提供某种服务,不是对整个 ...
- linux下的守护进程daemon
什么是守护进程?其实感觉守护进程并没有什么明确的定义,只是守护进程有一些特征,这是它需要遵循的. 守护进程的第一个特征是长时间在后台运行的程序,并且主要是为了提供某种服务,而为了能够让服务尽可能随时都 ...
随机推荐
- 攻防世界 你知道什么是cookie吗?
打开题目链接,提示我们查看cookie,cookie是HTTP协议中的一个重要参数,(对HTTP协议不是很熟悉的friends可以看看这个“HTTP协议其实就是这么简单”) 查看cookie的方法有很 ...
- FULL OUTER JOIN
FULL OUTER JOIN 关键字只要左表(table1)和右表(table2)其中一个表中存在匹配,则返回行. SELECT Web.name, access.count, access.dat ...
- 吴裕雄 python 人工智能——基于Mask_RCNN目标检测(2)
import os import sys import itertools import math import logging import json import re import random ...
- 使用node查询数据库(mysql)时,日期格式不对的问题。
https://blog.csdn.net/chanlingmai5374/article/details/93190983 1.问题场景 数据库里存了 datetime.但 Node 查询出来是这样 ...
- PHP扩展安装之phpize
phpize命令是准备php扩展安装的编译环境的.用于手动编译安装php扩展. 一般使用pecl来安装php扩展. 如果pecl没法安装,比如在防火墙后面,或要安装的扩展在pecl还没有兼容包.则使用 ...
- JZOJ5915 [2018NOIP模拟] 明日之星(广义后缀自动机,线段树)
题目描述 给定一棵树,每个节点有一个权值 \(a_i\) 和一个字符串 \(s_i\). q组询问,每次询问一个字符串 S 和两个节点x,y: 求x到y路径上每个节点的字符串在 S 中出现的次数乘上各 ...
- 企业面试问题收集-java基础
Java基础部分 1.1 在登录时进行后台验证,后台获取到loginpass与数据库值对比一直? 1.2 Java中的方法覆盖(Overwrite)和方法重载(Overloading)是什么意 ...
- centsos 7 删除自带jdk安装自定义jdk8
甲骨文官网地址:https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 如何清除自带j ...
- .NET中的字符串(5):字符串驻留
StringBuilder对象 通过上面的分析可以看出,String类型在做字符串的连接操作时,效率是相当低的,并且由于每做一个连接操作,都会在内存中创建一个新的对象,占用了大量的内存空间.这样就引出 ...
- systomctl与service的区别主要是版本区别
redhat和centos在7及以后的版本,用systemctl命令 redhat和centos在6及6以前的版本,用service命令. 两者的区别,如下. 举例 这里的.service可以不写,如 ...