守护进程

  守护进程,也就是通常说的Daemon进程,是Linux中的后台服务进程。它是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。守护进程常常在系统引导装入时启动,在系统关闭时终止。Linux系统有很多守护进程,大多数服务都是通过守护进程实现的。

守护进程的特点

  由于在Linux中,每一个系统与用户进行交流的界面称为终端,每一个从此终端开始运行的进程都会依附于这个终端,这个终端就称为这些进程的控制终端,当控制终端被关闭时,相应的进程都会自动关闭。但是守护进程却能够突破这种限制,它从被执行开始运转,直到整个系统关闭时才退出。如果想让某个进程不因为用户或终端或其他地变化而受到影响,那么就必须把这个进程变成一个守护进程。

  守护进程的概念类似于我们手机后台运行的程序,我们看不见它,它却一直在运行。在Windows系统下也有很多服务,都是所谓的守护进程。

服务器与守护进程

  Linux的大多数服务器就是用守护进程实现的。比如,Internet服务器inetd,Web服务器httpd等。同时,守护进程完成许多系统任务。

  正因为服务器的特点,守护进程在服务器开发上就很重要。

守护进程的创建和使用

  守护进程的创建主要分为以下几个部分:

  • 创建子进程,父进程退出
  • 在子进程中创建新会话
  • 改变当前目录为根目录
  • 重设文件权限掩码
  • 关闭文件描述符
  • 守护进程的退出

1.创建子进程,父进程退出

  由于守护进程是脱离控制终端的,因此会在Shell终端里造成一程序已经运行完毕的假象,也就是后台运行。在Linux中父进程先于子进程退出会造成子进程成为孤儿进程,而每当系统发现一个孤儿进程时,就会自动由1号进程(init)收养它,这样,原先的子进程就会变成init进程的子进程。

if(pid=fork())
exit(); //是父进程,结束父进程 

2.在子进程中创建新会话

  由于调用了fork函数时,子进程全盘拷贝了父进程的会话期、进程组、控制终端等,虽然父进程退出了,但会话期、进程组、控制终端等并没有改变,因此,这还不是真正意义上的独立开来,而setsid函数能够使进程完全独立出来,从而摆脱其他进程的控制。 

setsid函数用于创建一个新的会话,并担任该会话组的组长。调用setsid有下面的3个作用:
  1. 让进程摆脱原会话的控制
  2. 让进程摆脱原进程组的控制
  3. 让进程摆脱原控制终端的控制

  其中,会话是一个或多个进程组的集合。通常,一个会话开始于用户登录,终止于用户退出,在此期间该用户运行的所有进程都属于这个会话期。

setsid();           //第一子进程成为新的会话组长和进程组长

3.改变当前目录为根目录

  使用fork创建的子进程继承了父进程的当前工作目录。

chdir("/");      //改变工作目录到/

4.重设文件权限掩码

  由于使用fork函数新建的子进程继承了父进程的文件权限掩码,它可能修改守护进程所创建程序的存取位。

  所以需要把文件权限掩码设置为0,可以大大增强该守护进程的灵活性。

umask();           //重设文件创建掩模

5.关闭文件描述符

  用fork函数新建的子进程会从父进程那里继承一些已经打开了的文件。这些被打开的文件可能永远不会被守护进程读写,但它们一样消耗系统资源,而且可能导致所在的文件系统无法卸下。

for(i=;i<MAXFILE;i++)  //关闭打开的文件
close(i);

6.守护进程退出

  当用户需要外部停止守护进程运行时,往往会使用 kill命令停止该守护进程。所以,守护进程中需要编码来实现kill发出的signal信号处理,达到进程的正常退出。

signal(SIGCHLD,SIG_IGN);

例子

//daemon.c
#include <unistd.h>
#include <signal.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/stat.h> void init_daemon(void)
{
int pid;
int i;
if(pid=fork())
exit(); //是父进程,结束父进程
else if(pid< )
return();
setsid(); //第一子进程成为新的会话组长和进程组长 //并与控制终端分离
if(pid=fork())
exit(); //是第一子进程,结束第一子进程
else if(pid< )
exit(); //是第二子进程,继续
//第二子进程不再是会话组长
for(i=;i< NOFILE;++i) //关闭打开的文件描述符
close(i); chdir("/"); //改变工作目录到/
umask(); //重设文件创建掩模
return;
}
//test.c
#include <stdio.h>
#include <time.h > void init_daemon(void);//守护进程初始化函数 main()
{
init_daemon();//初始化为Daemon while(){
sleep(时间);
处理函数... ;
}
}

  注意,想要关闭后台程序,可以使用"Kill 进程标识符"的命令,查看进程状态可以使用ps -ef。

参考

http://baike.baidu.com/view/53123.htm

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


Server Develop (七) Linux 守护进程 由 cococo点点 创作,采用 知识共享 署名-非商业性使用-相同方式共享 3.0 中国大陆 许可协议进行许可。欢迎转载,请注明出处:
转载自:cococo点点 http://www.cnblogs.com/coder2012

Server Develop (七) Linux 守护进程的更多相关文章

  1. [转]❲阮一峰❳Linux 守护进程的启动方法

    ❲阮一峰❳Linux 守护进程的启动方法 "守护进程"(daemon)就是一直在后台运行的进程(daemon). 本文介绍如何将一个 Web 应用,启动为守护进程. 一.问题的由来 ...

  2. Linux守护进程详解(init.d和xinetd) [转]

    一 Linux守护进程 Linux 服务器在启动时需要启动很多系统服务,它们向本地和网络用户提供了Linux的系统功能接口,直接面向应用程序和用户.提供这些服务的程序是由运行在后台 的守护进程来执行的 ...

  3. Linux守护进程详解(init.d和xinetd)

    一 Linux守护进程 Linux 服务器在启动时需要启动很多系统服务,它们向本地和网络用户提供了Linux的系统功能接口,直接面向应用程序和用户.提供这些服务的程序是由运行在后台的守护进程来执行的. ...

  4. Linux守护进程的编程实现

    Linux 守护进程的编程方法 守护进程(Daemon)是执行在后台的一种特殊进程.它独立于控制终端而且周期性地执行某种任务或等待处理某些发生的事件.守护进程是一种非常实用的进程.Linux的大多数s ...

  5. CentOS 7.4 初次手记:第一章 Linux守护进程(daemon)

    第一节 init & sysvinit 6 I sysvinit 运行顺序... 6 II Sysvinit和系统关闭... 7 III Sysvinit 的小结... 7 IV 运行级别.. ...

  6. Linux守护进程简单介绍和实例具体解释

    Linux守护进程简单介绍和实例具体解释 简单介绍 守护进程(Daemon)是执行在后台的一种特殊进程.它独立于控制终端而且周期性地执行某种任务或等待处理某些发生的事件.守护进程是一种非常实用的进程. ...

  7. Linux守护进程及Systemd

    当我们启动一个前台任务后,命令行窗口退出,应用也就一起退出,无法访问了.怎么才能让它变成系统的守护进程(daemon),成为一种服务(service),一直在那里运行呢? 守护进程 前台任务和后台任务 ...

  8. .NET跨平台实践:用C#开发Linux守护进程

    Linux守护进程(Daemon)是Linux的后台服务进程,它脱离了与控制终端的关联,直接由Linux init进程管理其生命周期,即使你关闭了控制台,daemon也能在后台正常工作. 一句话,为L ...

  9. .NET跨平台实践:用C#开发Linux守护进程(转)

    Linux守护进程(Daemon)是Linux的后台服务进程,它脱离了与控制终端的关联,直接由Linux init进程管理其生命周期,即使你关闭了控制台,daemon也能在后台正常工作. 一句话,为L ...

随机推荐

  1. [笔记]Modelsim系列01:编译Altera库的方法

    意义:一劳永逸,不用每次对那些包含Quartus II生成文件的工程进行功能仿真时,都需要重新编译一堆东西.节约时间成本. 版本:ModelSim SE 6.5d 打开Modelsim软件,默认会打开 ...

  2. oVirt-engine项目UI结构

    1.管理面板文件路径 ovirt-engine/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmi ...

  3. HTML5基础

    一.HTML(超文本标记语言) 1>就是文本,由浏览器负责将它解析成具体的网页内容 2>由N个标签(节点.元素.标记)组成 二.常见HTML标签 1>标题标签:h1.h2.h3.h4 ...

  4. RAID简述

    RAID:Redundant Arrays of Independent Disks(独立冗余磁盘阵列) ①磁盘阵列是由很多价格较便宜的磁盘,组合成一个容量巨大的磁盘组,利用个别磁盘提供数据所产生加成 ...

  5. JAVA通过HTTP访问:Post+Get方式(转)

    public class TestGetPost { /** * 向指定URL发送GET方法的请求 * @param url 发送请求的URL * @param param 请求参数,请求参数应该是n ...

  6. POJ 3281 Dining

    Dining Description Cows are such finicky eaters. Each cow has a preference for certain foods and dri ...

  7. javascript 按ctrl和enter键提交表单

    <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8&qu ...

  8. zzulioj 1907小火山的宝藏交易(dfs记忆化搜索)

    #include <stdio.h> #include <algorithm> #include <string.h> #include <vector> ...

  9. redis学习(二) Redis Hash

    Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象. Redis 中每个 hash 可以存储 232 - 1 键值对(40多亿). redis ...

  10. C# 从excel里面复制的1万6千多条记录粘贴到FCKeditor里面,点保存的时候,保存不了,页面没有反应

    客户那边添加公告,是直接从excel里面复制的,有1万6千多条记录,excel文件有6M多. 编辑器用的FCKeditor,也能粘贴上,就是点保存的时候,执行了一段时间就没有反映了,保存不了. 想着可 ...