http://blog.csdn.net/zg_hover/article/details/2553321

守护进程(Daemon)是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。守护进程是一种很有用的进程。 Linux的大多数服务器就是用守护进程实现的。比如,Internet服务器inetd,Web服务器httpd等。 同时,守护进程完成许多系统任务。比如,作业规划进程crond,打印进程lpd等。

  1. .基本概念
  2. .进程
  3. .每个进程都有一个父进程
  4. .当子进程终止时,父进程会得到通知并能取得子进程的退出状态。
  5. .进程组
  6. .每个进程也属于一个进程组
  7. .每个进程主都有一个进程组号,该号等于该进程组组长的PID
  8. .一个进程只能为它自己或子进程设置进程组ID
  9. .会话期
  10. .对话期(session)是一个或多个进程组的集合。
  11. .setsid()函数可以建立一个对话期:
  12. 如果,调用setsid的进程不是一个进程组的组长,此函数创建一个新的会话期。
  13. (1)此进程变成该对话期的首进程
  14. (2)此进程变成一个新进程组的组长进程。
  15. (3)此进程没有控制终端,如果在调用setsid前,该进程有控制终端,那么与该终端的联系被解除。
  16. 如果该进程是一个进程组的组长,此函数返回错误。
  17. (4)为了保证这一点,我们先调用fork()然后exit(),此时只有子进程在运行,
  18. 子进程继承了父进程的进程组ID,但是进程PID却是新分配的,所以不可能是新会话的进程组的PID
  19. 从而保证了这一点。
  20.  
  21. if((pid=fork())>0) //parent
  22. exit(0);
  23. else if(pid==0){ //th1 child
  24. setsid(); //th1是成为会话期组长,使得与运行前的环境隔离开来
  25. if(fork() ==0){ //th2不会是会话期组长(变成孤儿进程组)
  26. ...
  27. }
  28. }
  1. 一. 守护进程及其特性
  2.  
  3. (1)守护进程最重要的特性是后台运行,即脱离控制终端。在这一点上DOS下的常驻内存程序TSR与之相似。
  4. (2)其次,守护进程必须与其运行前的环境隔离开来。这些环境包括未关闭的文件描述符,控制终端,
  5. 会话和进程组,工作目录以及文件创建掩模等。这些环境通常是守护进程从执行它的父进程(特别是shell
  6. 中继承下来的。
  7. (3)最后,守护进程的启动方式有其特殊之处。它可以在Linux系统启动时从启动脚本/etc/rc.d中启动,
  8. 可以由作业规划进程crond启动,还可以由用户终端(通常是 shell)执行。
  9.   总之,除开这些特殊性以外,守护进程与普通进程基本上没有什么区别。
  10. 因此,编写守护进程实际上是把一个普通进程按照上述的守护进程的特性改造成为守护进程。
  1. 二. 守护进程的编程要点 (来自UEAP)
  2.  
  3.   前面讲过,不同Unix环境下守护进程的编程规则并不一致。所幸的是守护进程的编程原则其实都一样,
  4. 区别在于具体的实现细节不同。这个原则就是要满足守护进程的特性。
  5. 同时,Linux是基于Syetem VSVR4并遵循Posix标准,实现起来与BSD4相比更方便。编程要点如下;
  6.  
  7. 1. 在后台运行。
  8.   为避免挂起控制终端将Daemon放入后台执行。方法是在进程中调用fork使父进程终止,
  9. Daemon在子进程中后台执行。
  10.  
  11. if(pid=fork())
  12. exit(0); //是父进程,结束父进程,子进程继续
  13.  
  14. 2. 脱离控制终端,登录会话和进程组
  15.   进程属于一个进程组,进程组号(GID)就是进程组长的进程号(PID)。登录会话可以包含多个进程组。
  16. 这些进程组共享一个控制终端。这个控制终端通常是创建进程的登录终端。
  17. 控制终端,登录会话和进程组通常是从父进程继承下来的。
  18. 我们的目的就是要摆脱它们,使之不受它们的影响。
  19. 方法是在第1点的基础上,调用setsid()使进程成为会话组长:
  20.  
  21. setsid();
  22.  
  23.   说明:当进程是会话组长时setsid()调用失败。但第一点已经保证进程不是会话组长。
  24. setsid()调用成功后,进程成为新的会话组长和新的进程组长,并与原来的登录会话和进程组脱离。
  25. 由于会话过程对控制终端的独占性,进程同时与控制终端脱离。
  26.  
  27. 3. 禁止进程重新打开控制终端
  28.   现在,进程已经成为无终端的会话组长。但它可以重新申请打开一个控制终端。
  29. 可以通过使进程不再成为会话组长来禁止进程重新打开控制终端:
  30.  
  31. if(pid=fork())
  32. exit(0); //结束第一子进程,第二子进程继续(第二子进程不再是会话组长)
  33.  
  34. 4. 关闭打开的文件描述符
  35.   进程从创建它的父进程那里继承了打开的文件描述符。如不关闭,将会浪费系统资源,
  36. 造成进程所在的文件系统无法卸下以及引起无法预料的错误。按如下方法关闭它们:
  37.  
  38. for(i=0;i 关闭打开的文件描述符close(i);>
  39.  
  40. 5. 改变当前工作目录
  41.   进程活动时,其工作目录所在的文件系统不能卸下。一般需要将工作目录改变到根目录。
  42. 对于需要转储核心,写运行日志的进程将工作目录改变到特定目录如 /tmpchdir("/")
  43.  
  44. 6. 重设文件创建掩模
  45.   进程从创建它的父进程那里继承了文件创建掩模。它可能修改守护进程所创建的文件的存取位。
  46. 为防止这一点,将文件创建掩模清除:umask(0);
  47.  
  48. 7. 处理SIGCHLD信号
  49.   处理SIGCHLD信号并不是必须的。
  50. 但对于某些进程,特别是服务器进程往往在请求到来时生成子进程处理请求。
  51. 如果父进程不等待子进程结束,子进程将成为僵尸进程(zombie)从而占用系统资源。
  52. 如果父进程等待子进程结束,将增加父进程的负担,影响服务器进程的并发性能。
  53. Linux下可以简单地将 SIGCHLD信号的操作设为SIG_IGN
  54.  
  55. signal(SIGCHLD,SIG_IGN);
  56.  
  57.   这样,内核在子进程结束时不会产生僵尸进程。
  58. 这一点与BSD4不同,BSD4下必须显式等待子进程结束才能释放僵尸进程。
  1. void init_daemon(void)
  2. {
  3. int pid;
  4. int i;
  5. if((pid=fork())>)
  6. exit();//退出父进程
  7. else if(pid<)
  8. exit();//fork失败
  9. //是第一子进程,后台继续执行
  10. setsid();//第一子进程成为新的会话组长和进程组长
  11. //并与控制终端分离
  12. if((pid=fork())>)
  13. exit();//第一子进程退出
  14. else if(pid<)
  15. exit();//fork失败
  16. //是第二子进程,继续
  17. //第二子进程不再是会话组长
  18.  
  19. for(i=;i<NOFILE;i++)//关闭打开的文件描述符
  20. close(i);
  21. chdir("/tmp");//改变工作目录到/temp
  22. umask();//重设文件创建掩码
  23.  
  24. return ;
  25. }
  1.  

【APUE】【转】守护进程编写的更多相关文章

  1. linux C守护进程编写

    linux编程-守护进程编写 守护进程(Daemon)是运行在后台的一种特殊进程.它独立于控制终端并且周期性地执行某种任务或等待 处理某些发生的事件.守护进程是一种很有用的进程. Linux的大多数服 ...

  2. Linux守护进程编写指南

    Linux守护进程编写指南 守护进程(Daemon)是运行在后台的一种特殊进程.它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件.守护进程是一种很有用的进 程.Linux的大多数服务器 ...

  3. linux守护进程编写实践

    主要参考:http://colding.bokee.com/5277082.html (实例程序是参考这的) http://wbwk2005.blog.51cto.com/2215231/400260 ...

  4. Linux守护进程编写方法及原理

    什么守护进程? 守护进程是运行在后台的一种用来提供服务的进程,他脱离控制台独立运行,守护进程是一种很有用的进 程. Linux的大多数服务器就是用守护进程实现的.比如,Internet服务器inetd ...

  5. 拾遗:Unix 守护进程编写规范

    //标准库自带函数,通常以 daemon(0, 0) 方式调用 int daemon(int nochdir, int noclose) Linux: #include <unistd.h> ...

  6. supervisor运行golang守护进程

    最近在鼓捣golang守护进程的实现,无意发现了supervisor这个有意思的东西.supervisor是一个unix的系统进程管理软件,可以用它来管理apache.nginx等服务,若服务挂了可以 ...

  7. Unix守护进程

    问题描述:         Unix守护进程 问题解决:     Unix守护进程没有控制终端,终端名设置为问号(?),终端前台进程组ID设置(TPGID)为-1 守护进程编写规则:      (1) ...

  8. 【转】学习Linux守护进程详细笔记

    [原文]https://www.toutiao.com/i6566814959966093837/ Linux守护进程 一. 守护进程概述 守护进程,也就是通常所说的Daemon进程,是Linux中的 ...

  9. 经典C/S服务器模型之守护进程

    linux编程-守护进程编写 守护进程(Daemon)是运行在后台的一种特殊进程.它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件.守护进程是一种很有用的进程. Linux的大多数服务 ...

随机推荐

  1. droplang - 删除一种 PostgreSQL 过程语言

    SYNOPSIS droplang [ connection-option...] langname [ dbname] droplang [ connection-option...] --list ...

  2. 进程池_Pool

    当需要创建子进程数量不多的时候,可以直接利用multiprocessing中的Process动态生成多个进程 但是如果是成百甚至上千个任务,手动地创建它的工作量很大,此时就可以利用到multiproc ...

  3. iview modal 点击打开窗口,打开前先销毁里面的内容再打开

    <Modal v-model="addSubOrgModal" @on-cancel="addSubOrgCancel" @on-visible-chan ...

  4. 基础数据类型(set集合)

    认识集合 由一个或多个确定的元素所构成的整体叫做集合. 集合中的元素有三个特征: 1.确定性(集合中的元素必须是确定的) 2.互异性(集合中的元素互不相同.例如:集合A={1,a},则a不能等于1) ...

  5. 解决margin塌陷问题

    父元素添加: border: 1px solid transparent; 或者 over-flow:hidden;

  6. python之字符串str操作方法

    str.upper() (全部大写) str.lower() (全部小写) str.startswith() (以什么开头) str.endswith() (以什么结尾) str.count() (统 ...

  7. luogu P1462 通往奥格瑞玛的道路--spfa+二分答案

    P1462 通往奥格瑞玛的道路 题目背景 在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量 有一天他醒来后发现自己居然到了联盟的主城暴风城 在被众多联盟的士兵攻击后,他决定逃回自己的家乡 ...

  8. ICPC-Beijing 2006 狼抓兔子

    题目描述 题解: 裸的最小割. 但是最大流跑不过去怎么办? 转变一下,既然最大流是一条左下<->右上的通路,我们可以把图划分为若干区域, 最后找左下到右上的最短路就行了. 代码: #inc ...

  9. 杭电 1856 More is better (并查集求最大集合)

    Description Mr Wang wants some boys to help him with a project. Because the project is rather comple ...

  10. 开门人和关门人(结构体+sort)

    每天第一个到机房的人要把门打开,最后一个离开的人要把门关好.现有一堆杂乱的机房签 到.签离记录,请根据记录找出当天开门和关门的人.    Input 测试输入的第一行给出记录的总天数N ( > ...