一、守护进程介绍

守护进程是在后台运行且不与任何控制终端相关联的进程。通常由系统初始化脚本启动,当然也可以在shell提示符下用命令行启动,不过这种守护进程必须亲自脱离于控制终端的关联。

守护进程的启动方法有:

1、系统初始化阶段,由系统初始化脚本启动。这些脚本通常位于/etc、/etc/rc开头的某个目录中。由这些脚本启动的守护进程从一开始就有root特权。例如:inetd超级服务器、Web服务器、邮件服务器、syslogd守护进程等都用这种方式启动。

注:系统初始化的时候,系统内运行着一些守护进程(syslogd inetd  ......)

2、靠inetd超级服务器启动。inetd超级服务器监听网络请求,每当有一个请求到达时,启动相应的实际服务器。

3、corn守护进程按照规则定期执行一些程序,由它启动执行的程序同样作为守护进程运行。Corn自身由第一种方式启动。

4、at命令用于指定将来某个时刻的程序执行。

5、从用户终端或者后台启动。这么做往往是为了测试守护程序或重启因某种原因而终止的守护进程。

二、syslogd守护进程

syslogd守护进程由系统初始化脚本启动,在系统工作期间一直运行。步骤如下:

1、读取配置文件;

2、创建一个数据报套接字,绑定/var/run/log

3、创建一个UDP套接字,绑定端口514

4、打开路径/dev/klog。

此后便一直运行,调用select等待它的3个描述符之一变成可读,然后读入日志消息,按照配置文件进行处理。(收到SIGHUP信号,重新读取配置文件)。

注:其他的进程(例如由inetd创建的守护进程)将自己所产生的输出通过调用syslog函数发送给syslogd进程,这些消息有lever和facility,系统管理员根据严重级别,做出不同的消息处理方式。

由于守护进程没有终端,所以它的消息用fprintf到stderr上,从守护进程登记消息使用syslog函数:

void syslog(int priority,const char *message,…);

三、如何把一个普通进程转变成守护进程?

使用daemon函数或者daemon_init函数。

编程要点:

1. 在后台运行 
   为避免挂起控制终端将Daemon放入后台执行。方法是在进程中调用fork使父进程终止,让Daemon在子进程中后台执行。 
if(pid=fork()) exit(0);    //是父进程,结束父进程,子进程继续 
2. 脱离控制终端,登录会话和进程组 
    有必要先介绍一下Linux中的进程与控制终端,登录会话和进程组之间的关系:进程属于一个进程组,进程组号(GID)就是进程组长的进程号(PID)。登录会话可以包含多个进程组。这些进程组共享一个控制终端。这个控制终端通常是创建进程的登录终端。控制终端,登录会话和进程组通常是从父进程继承下来的。我们的目的就是要摆脱它们 ,使之不受它们的影响。方法是在第1点的基础上,调用setsid()使进程成为会话组长: 
setsid(); 
    说明:当进程是会话组长时setsid()调用失败。但第一点已经保证进程不是会话组长。setsid()调用成功后,进程成为新的会话组长和新的进程组长,并与原来的登录会话和进程组脱离。由于会话过程对控制终端的独占性,进程同时与控制终端脱离。 
3. 禁止进程重新打开控制终端 
    现在,进程已经成为无终端的会话组长。但它可以重新申请打开一个控制终端。可以通过使进程不再成为会话组长来禁止进程重新打开控制终端: 
if(pid=fork()) exit(0);  //结束第一子进程,第二子进程继续(第二子进程不再是会话组长) 
4. 关闭打开的文件描述符 
    进程从创建它的父进程那里继承了打开的文件描述符。如不关闭,将会浪费系统资源,造成进程所在的文件系统无法卸下以及引起无法预料的错误。按如下方法关闭它们: 
for(i=0;i 关闭打开的文件描述符close(i);
5. 改变当前工作目录 
    进程活动时,其工作目录所在的文件系统不能卸下。一般需要将工作目录
改变到根目录 。对于需要转储核心,写运行日志的进程将工作目录改变到特定目录如/tmp

chdir("/")

6. 重设文件创建掩模 
   进程从创建它的父进程那里继承了文件创建掩模。它可能修改守护进程所创建的文件的存取位。为防止这一点,将文件创建掩模清除:

umask(0);

7. 处理SIGCHLD信号 

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

这样,内核在子进程结束时不会产生僵尸进程。这一点与BSD4不同,BSD4下必须显式等待子进程结束才能释放僵尸进程。

四、inetd守护进程

典型的unix系统可能存在许多服务器,它们只是等待客户请求的到达,如FTP、Telnet、Rlogin、TFTP等。最开始,所有的这些服务都与一个进程相关联,这些进程在系统启动时开始运行,而且执行几乎相同的启动任务:创建一个套接口,把本服务的众所周知的端口捆绑到该套接口,等待一个连接(TCP)或是一个数据报(UDP),然后派生子进程。子进程为客户提供服务,父进程则等待下一个客户请求。这个模型存在两个问题:

1.  所有这些守护进程含有几乎相同的启动代码(套接口的创建以及成为守护进程)。

2.  每个守护进程在进程表中占据一项,并且大部分时间处于睡眠状态。

inetd超级服务器使上述的问题得到简化:

1. 通过inetd处理普通进程的大部分细节以简化守护程序的编写。

2. 单个进程(inetd)就能为多个服务等待外来的客户请求,以此取代每个服务一个进程的做法,减少了系统中的进程数。

initd守护进程的工作流程:

1,在启动阶段,读入/etc/inetd.conf文件并给该文件中指定的每个服务创建一个适当类型的套接口。
2,为每个套接口调用bind,指定捆绑相应服务器的众所周知端口和通配IP地址。
3,对于每个TCP套接口,调用listen以接受外来的连接请求。对于数据报套接口则不执行本步骤。
4,创建完毕所有套接口后,调用select等待其中任何一个套接口变为可读。
5,当select返回指出某个套接口已可读之后,如果该套接口是一个TCP套接口,而且其服务器的wait-flag值为nowait,那就调用accept接受这个新连接。
6,inetd守护进程调用fork派生进程,并由子进程处理服务请求。
7,如果第5步中select返回的是一个字节流套接口,那么父进程必须关闭接受了的已连接套接口,父进程再次调用select,等待下一个变为可读的套接口。

如果5)中,其服务器的wait-flag值为wait的话,对于数据报服务,父进程应该禁止相应的套接字(通过关闭select描述符集合中对应的位),防止select再次返回可读条件。这就意味着子进程接管了这个套接字直到自身终止为止。一旦子进程自身终止后,父进程就会被通知一个sigchld信号,而父进程此时就会获得子进程的pid。父进程通过再次打开相应的套接字的位,使得该套接字再次成为select的候选套接字。

那么,为什么要这么做呢?

原因其实是,数据报服务器只有一个套接字,它不像tcp有监听套接字也有连接套接字。如果inetd不关闭对于某个数据报套接字的可检查条件,而且父进程有又是先于子进程执行,那么引发本次fork的那个数据报仍然在套接字接收缓冲区,导致select再次返回可读条件,导致inetd进程再次fork另一个不必要的子进程。(UNP p297页)

守护进程和inetd守护进程相关推荐

  1. 守护进程和inetd(转)

    定义: 守护进程 daemon 是在后台运行不受终端控制的进程. 启动方法: 1.        很多守护进程是系统初始化脚本启动的,一般在/etc目录或者/etc/rc开头的目录 2.        ...

  2. 守护进程和inetd超级服务器

    守护进程是在后台运行且不与任何控制终端关联的进程.既然守护进程没有控制终端,当有事情发生时,它们得有输出消息的某种方法,syslog函数是输出这些消息的标准方法,它把这些消息发送给syslogd守护进 ...

  3. linux守护进程fifo,linux守护进程配置文件

    syslogd 是一种守护进程,它负责记录(写到磁盘)从其它程序发送到系统的消息.这个服务尤其常被某些守护进程所使用,这些守护进程不会有另外的方法来发出可能有问题存在的信号或向用户发送消息. 1.文件 ...

  4. Python 多进程笔记 — 启动进程的方式、守护进程、进程间通信、进程池、进程池之间通信、多进程生产消费模型

    1 面向过程启动多进程 Python 操作进程的类都定义在 multiprocessing 模块,该模块提供了一个 Process 类来代表一个进程对象,这个对象可以理解为是一个独立的进程,可以执行另 ...

  5. Linux多进程开发(三)进程创建之守护进程的学习

       之前发过一篇守护进程的文章,但是解析的不够详细,这次,详细来解释守护进程的一些概念和特性.   概念: 后台运行.没有控制端与之相连的进程.独立于控制终端,通常周期性的执行某种任务.    Wh ...

  6. android双进程守护耗电,Android实现双进程守护

    做过android开发的人应该都知道应用会在系统资源匮乏的情况下被系统杀死!当后台的应用被系统回收之后,如何重新恢复它呢?网上对此问题有很多的讨论.这里先总结一下网上流传的各种解决方案,看看这些办法是 ...

  7. python守护进程_Python实现守护进程

    考虑如下场景:你编写了一个python服务程序,并且在命令行下启动,而你的命令行会话又被终端所控制,python服务成了终端程序的一个子进程.因此如果你关闭了终端,这个命令行程序也会随之关闭. 要使你 ...

  8. supervisor 守护多个进程_supervisor管理守护进程

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

  9. Linux系统编程---11(会话,守护进程,创建守护进程)

    会话 创建会话 创建一个会话需要注意以下6点注意事项 调用进程不能是进程组组长,该进程变成新会话首进程 该进程成为一个新进程组的组长进程 需要root权限(nbuntu不需要) 新会话丢弃原有的控制终 ...

最新文章

  1. memcache协议
  2. 11家车企联手高通、大唐,加速V2X在华商用部署
  3. Adobe把GAN搞成了缝合怪,凭空P出一张1024分辨率全身人像 | CVPR 2022
  4. xdm,把我大学四年能用到的软件都分享给你。
  5. P3201-[HNOI2009]梦幻布丁【启发式合并,链表】
  6. 01背包问题,动态规划求解
  7. UVA 11452 Dancing the Cheeky-Cheeky
  8. 用指针交换两个数_LeetCode双指针系列
  9. .NET----错误和异常处理机制
  10. mysql 主从库_MySQL数据库之mysql 主库有数据通过锁库做主从
  11. 查看User Profile的名称和显示名称
  12. 如何打开屏幕坏的手机_手机屏幕坏了怎么打开usb调试
  13. FlashBuilder使用
  14. 【DjangoDRF+缓存+JWT+RabbitMQ 七万字总结】
  15. MySql 新增数据
  16. Markdown 内如何使用表情符号
  17. Sepic电路的参数计算及仿真
  18. 【C语言】消失的数字
  19. 【小沐学NLP】Python实现词云图
  20. Spring Boot项目学习之通用权限管理项目01

热门文章

  1. Nginx的负载均衡 - 保持会话 (ip_hash)
  2. 【转】(原創) 如何使用ModelSim-Altera對Nios II仿真? (SOC) (Nios II) (SOPC Builder) (ModelSim) (DE2)...
  3. ASP.net Xml: ASP.net操作Xml
  4. 求解最长单调递增子串
  5. Linux命令行下登录ssl加密的ftp
  6. gcc/g++命令参数笔记
  7. linux shell编程控制结构:expr、let、for、while、until、shift、if、case、break、continue、函数、select 学习笔记
  8. MySQL python update 语句
  9. 关于路径搜索的算法, 可能用到
  10. Docker(五):Docker 三剑客之 Docker Machine