文档章节

守护进程daemon详解

 随性_
发布于 2016/07/15 11:21
字数 2031
阅读 184
收藏 6
点赞 0
评论 0

一:守护进程概述

Linux Daemon(守护进程)是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。它不需要用户输入就能运行而且提供某种服务,不是对整个系统就是对某个用户程序提供服务。Linux系统的大多数服务器就是通过守护进程实现的。常见的守护进程包括系统日志进程syslogd、 web服务器httpd、邮件服务器sendmail和数据库服务器mysqld等。

二:创建守护进程步骤:

首先我们要了解一些基本概念:

  • 每个进程属于一个进程组
  • 每个进程组有组号和组长,组长进程的pid就是该进程组的组号(pgid)
  • 一个进程只能为它自己或子进程设置进程组ID号

会话期:

会话期(session)是一个或多个进程组的集合,当集合中只有一个进程组时,sid与该进程组 组长的pid相同,这些进程组共享一个控制终端。这个控制终端通常是创建进程的登录终端,控制终端,登录会话和进程组通常是从父进程继承下来的。

setsid()函数可以建立一个对话期:

 如果,调用setsid的进程不是一个进程组的组长,此函数创建一个新的会话期;如果是该进程组的组长,则此函数返回错误

(1)此进程变成该对话期的首进程

(2)此进程变成一个新进程组的组长进程

(3)此进程没有控制终端,如果在调用setsid前,该进程有控制终端,那么与该终端的联系被解除

(4)为了保证这一点,我们先调用fork()然后exit(),此时只有子进程在运行,fork后的子进程pid是重新分配的,即保证了此时运行的进程永远不会是进程组的组长

现在我们来给出创建守护进程所需步骤:

编写守护进程的一般步骤步骤:

(1)在父进程中执行fork并exit推出;

(2)在子进程中调用setsid函数创建新的会话;

(3)在子进程中调用chdir函数,让根目录 ”/” 成为子进程的工作目录;

(4)在子进程中调用umask函数,设置进程的umask为0;

(5)在子进程中关闭任何不需要的文件描述符

以图解两次fork的过程:

前提,会话中只有一个进程组,进程组中只有一个进程;

pid ppid pgid(组id) sid(session id) 组长(y/n)
100 10 100 100 y

第一次fork时:

pid ppid pgid(组id) sid(session id) 组长(y/n)
100 10 100 100 y
101 100 100(extends parent) 100 n

exit父进程:

pid ppid pgid(组id) sid(session id) 组长(y/n)
101 100 100 100 n

init进程接管:

pid ppid pgid(组id) sid(session id) 组长(y/n)
101 1 100 100 n

执行setsid后:

pid ppid pgid(组id) sid(session id) 组长(y/n)
101 1 101 101 y

第二次fork:

pid ppid pgid(组id) sid(session id) 组长(y/n)
101 1 101 101 y
102 101 101 101 n

exit父进程:

pid ppid pgid(组id) sid(session id) 组长(y/n)
102 101 101 101 n

由init进程接管:

pid ppid pgid(组id) sid(session id) 组长(y/n)
102 1 101 101 n

三:守护进程的编写步骤

  1. fork子进程,而后父进程退出,此时子进程会被init进程接管
  2. 修改子进程的工作目录、创建新进程组和新会话、修改umask
  3. 子进程再次fork一个进程,这个进程可以称为孙子进程,而后子进程退出,此时子进程会被init进程接管
  4. 重定向孙子进程的标准输入流、标准输出流、标准错误流到/dev/null。

完成上面的4个步骤,那么最终的孙子进程就称为守护进程。先看下代码,后面再分析下每个步骤的原因。

#!/usr/bin/env python

#coding=utf8

import os, sys, time

#产生子进程,而后父进程退出

pid = os.fork()

if pid > 0:

  sys.exit(0)


#修改子进程工作目录

os.chdir("/")

#创建新的会话,子进程成为会话的首进程

os.setsid()

#修改工作目录的umask

os.umask(0)

#创建孙子进程,而后子进程退出

pid = os.fork()

if pid > 0:

  sys.exit(0)


#重定向标准输入流、标准输出流、标准错误

sys.stdout.flush()

sys.stderr.flush()

si = file("/dev/null", 'r')

so = file("/dev/null", 'a+')

se = file("/dev/null", 'a+', 0)

os.dup2(si.fileno(), sys.stdin.fileno())

os.dup2(so.fileno(), sys.stdout.fileno())

os.dup2(se.fileno(), sys.stderr.fileno())



#孙子进程的程序内容

while True:

    time.sleep(10)

    f = open('/home/test.txt', 'a')

    f.write('hello')

上面的程序没有任何错误处理,但是不影响原理分析。如果要应用到项目里,还需完善。下面笔者谈下自己对每个步骤的理解。

1、fork子进程,父进程退出

通常,我们执行服务端程序的时候都会通过终端连接到服务器,成功连接后会加载shell环境,终端和shell都是进程,shell进程是终端进程的子进程,通过ps命令可以很容易的查看到。在这个shell环境下一开始执行的程序都是shell进程的子进程,自然会受到shell进程的影响。在程序里fork子进程后,父进程退出,对了shell进程来说,这个父进程就算执行完了,而产生的子进程会被init进程接管,从而也就脱离了终端的控制。

2、关闭打开的文件描述符和修改子进程的工作目录

进程从创建它的父进程那里继承了打开的文件描述符。如不关闭,将会浪费系统资源,造成进程所在的文件系统无法卸下以及引起无法预料的错误,子进程在创建的时候会继承父进程的工作目录,如果执行的程序是在u盘里的,就会导致u盘不能卸载。

3、创建新会话

使用setsid后,子进程就会成为新会话的首进程(session leader);子进程会成为新进程组的组长进程;子进程没有控制终端。

4、修改umask

由于umask会屏蔽权限,所以设定为0,这样可以避免读写文件时碰到权限问题。

5、fork孙子进程,子进程退出

经过上面几个步骤后,子进程会成为新的进程组老大,可以重新申请打开终端,为了避免这个问题,fork孙子进程出来。

6、重定向孙子进程的标准输入流、标准输出流、标准错误流到/dev/null

因为是守护进程,本身已经脱离了终端,那么标准输入流、标准输出流、标准错误流就没有什么意义了。所以都转向到/dev/null,就是都丢弃的意思。

7. 处理SIGCHLD信号 
处理SIGCHLD信号并不是必须的。但对于某些进程,特别是服务器进程往往在请求到来时生成子进程处理请求。如果父进程不等待子进程结束,子进程将成为僵尸进程(zombie)从而占用系统资源。如果父进程等待子进程结束,将增加父进程的负担,影响服务器进程的并发性能。在Linux下可以简单地将SIGCHLD信号的操作设为SIG_IGN。 
signal(SIGCHLD,SIG_IGN); 

参考资料:

http://www.01happy.com/linux-python-daemon/

http://www.cnblogs.com/mickole/p/3188321.html

http://blog.csdn.net/jason314/article/details/5640969


针对守护这个概念延伸到python,python也有守护线程的概念

python daemon理解:
    守护进程只与主进程有相互作用关系;主线程结束为前提,守护进程保证所有的子线程都执行完后就全部退出,即使守护进程没有执行完进程也会退出;

参考资料:

http://www.dongwm.com/archives/guanyuthreadingyanjiuer/

© 著作权归作者所有

共有 人打赏支持
粉丝 8
博文 16
码字总数 18722
作品 0
南昌
supervisor安装和配置指南

supervisor:是用python写的一个进程管理工具,用来启动,重启,关闭进程。 注意:Supervisor只能管理非daemon的进程,也就是说Supervisor不能管理守护进程。否则提示Exited too quickly (p...

高运维之路
05/03
0
0
[转] chcon 命令详解

chcon命令:修改对象(文件)的安全上下文。比如:用户:角色:类型:安全级别。 命令格式: Chcon [OPTIONS…] CONTEXT FILES….. Chcon [OPTIONS…] –reference=PEF_FILES FILES… 说明:...

鉴客
2012/09/18
860
0
Linux 进程管理与监控(supervisor and monit)

一、Supervisor 1、安装 宿主机环境:( Centos 6.5 ) pip2.7 install supervisor 2、创建配置文件 通过 echosupervisordconf 命令来创建配置文件: echosupervisordconf >/etc/supervisord.co......

qw87112
06/28
0
0
Linux 守护进程

一、基本概念 守护进程一般在系统启动时开始运行,除非强行终止,否则直到系统关机都保持运行。守护进程经常以超级用户(root)权限运行,因为它们要使用特殊的端口(1-1024)或访问某些特殊...

吃一堑消化不良
2016/12/09
17
0
Unix环境高级编程笔记 :13、守护进程

1 守护进程 守护进程也称精灵进程(daemon)是生存期较长的一种进程。它们常常在系统自举时启动,仅在系统关闭时才终止。 因为没的控制终端,所以它们是在后台运行的。 2、守护进程特征 父进程...

活的很快乐
2013/11/19
0
0
Linux守护进程之Supervisor

什么是守护进程 在linux或者unix操作系统中,守护进程(Daemon)是一种运行在后台的特殊进程,它独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件。由于在linux中,每个系统...

OneTODO
2016/10/31
47
0
Python 的多进程编程方法 之 multiprocessing(一)

由于os模块的fork不能在windwos上运行而选择multiprocessing模块,并且此模块提供更加强大的进程管理、资源共享、分布式机制。 首先我们来一个简单的例子: # -- encoding:utf-8-- import m...

水果糖
2016/03/16
164
0
Linux多任务编程(七)---Linux守护进程及其基础实验

守护进程概述 守护进程,又叫daemon进程(不知怎的,我突然想起来吸血鬼日记中的达蒙了,很好看的美剧),是Linux中的后台服务进程。他是一个生存期较长的进程,通常独立于控制终端并且周期性地...

长平狐
2013/06/17
78
0
Docker 命令行与守护进程如何交互?

译者按: Docker是典型的C/S架构,其守护进程(daemon)与命令行(CLI)是通过REST API进行交互的。 原文: Understanding how the Docker Daemon and Docker CLI Work Together 译者: Fundebug 为...

Fundebug
2017/05/31
0
0
python下编写守护进程

1、编写守护进程的步骤 Python创建守护进程其实和c创建守护进程的方式大同小异了,其实就是那么几个步骤: (1)创建子进程,父进程退出 (2)改变当前目录为根目录 (3)在子进程中创建新会...

翼动动空
2016/05/08
689
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

SpringBoot | 第十章:Swagger2的集成和使用

前言 前一章节介绍了mybatisPlus的集成和简单使用,本章节开始接着上一章节的用户表,进行Swagger2的集成。现在都奉行前后端分离开发和微服务大行其道,分微服务及前后端分离后,前后端开发的...

oKong
今天
9
0
Python 最小二乘法 拟合 二次曲线

Python 二次拟合 随机生成数据,并且加上噪声干扰 构造需要拟合的函数形式,使用最小二乘法进行拟合 输出拟合后的参数 将拟合后的函数与原始数据绘图后进行对比 import numpy as npimport...

阿豪boy
今天
4
0
云拿 无人便利店

附近(上海市-航南路)开了家无人便利店.特意进去体验了一下.下面把自己看到的跟大家分享下. 经得现场工作人员同意后拍了几张照片.从外面看是这样.店门口的指导里强调:不要一次扫码多个人进入....

周翔
昨天
1
0
Java设计模式学习之工厂模式

在Java(或者叫做面向对象语言)的世界中,工厂模式被广泛应用于项目中,也许你并没有听说过,不过也许你已经在使用了。 简单来说,工厂模式的出现源于增加程序序的可扩展性,降低耦合度。之...

路小磊
昨天
172
1
npm profile 新功能介绍

转载地址 npm profile 新功能介绍 npm新版本新推来一个功能,npm profile,这个可以更改自己简介信息的命令,以后可以不用去登录网站来修改自己的简介了 具体的这个功能的支持大概是在6这个版...

durban
昨天
1
0
Serial2Ethernet Bi-redirection

Serial Tool Serial Tool is a utility for developing serial communications, custom protocols or device testing. You can set up bytes to send accordingly to your protocol and save......

zungyiu
昨天
1
0
python里求解物理学上的双弹簧质能系统

物理的模型如下: 在这个系统里有两个物体,它们的质量分别是m1和m2,被两个弹簧连接在一起,伸缩系统为k1和k2,左端固定。假定没有外力时,两个弹簧的长度为L1和L2。 由于两物体有重力,那么...

wangxuwei
昨天
0
0
apolloxlua 介绍

##项目介绍 apolloxlua 目前支持javascript到lua的翻译。可以在openresty和luajit里使用。这个工具分为两种模式, 一种是web模式,可以通过网页使用。另外一种是tool模式, 通常作为大规模翻...

钟元OSS
昨天
2
0
Mybatis入门

简介: 定义:Mybatis是一个支持普通SQL查询、存储过程和高级映射的持久层框架。 途径:MyBatis通过XML文件或者注解的形式配置映射,实现数据库查询。 特性:动态SQL语句。 文件结构:Mybat...

霍淇滨
昨天
2
0
开发技术瓶颈期,如何突破

前言 读书、学习的那些事情,以前我也陆续叨叨了不少,但总觉得 “学习方法” 就是一个永远在路上的话题。个人的能力、经验积累与习惯方法不尽相同,而且一篇文章甚至一本书都很难将学习方法...

_小迷糊
昨天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部