什么是守护进程?
守护进程(Daemon Process),也就是通常说的 Daemon 进程(精灵进程),是 Linux 中的后台服务进程。它是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。

守护进程是个特殊的孤儿进程,这种进程脱离终端,为什么要脱离终端呢?之所以脱离于终端是为了避免进程被任何终端所产生的信息所打断,其在执行过程中的信息也不在任何终端上显示。由于在 Linux 中,每一个系统与用户进行交流的界面称为终端,每一个从此终端开始运行的进程都会依附于这个终端,这个终端就称为这些进程的控制终端,当控制终端被关闭时,相应的进程都会自动关闭。

Linux 的大多数服务器就是用守护进程实现的。比如,Internet 服务器 inetd,Web 服务器 httpd 等。

#include "apue.h"
#include <syslog.h>
#include <fcntl.h>
#include <sys/resource.h>

void daemonize(const char *cmd){
  int i, fd0, fd1, fd2;
  pid_t pid;
  struct rlimit rl;
  struct sigaction sa;

  /* * Clear file creation mask. */
  umask(0);//因为我们从shell创建的daemon子进程,所以daemon子进程会继承shell的umask,如果不清除的话,会导致daemon进程创建文件时屏蔽某些权限。

  /* * Get maximum number of file descriptors. */
  if (getrlimit(RLIMIT_NOFILE, &rl) < 0)
    err_quit("%s: can't get file limit", cmd);

  /* * Become a session leader to lose controlling TTY. */
  if ((pid = fork()) < 0)//fork后让父进程退出,子进程获得新的pid,肯定不为进程组组长,这是setsid前提。
    err_quit("%s: can't fork", cmd);
  else if (pid != 0) /* parent */
    exit(0);
  setsid();//调用setsid来创建新的进程会话。这使得daemon进程成为会话首进程,脱离和terminal的关联。

  /* * Ensure future opens won't allocate controlling TTYs. */
  sa.sa_handler = SIG_IGN;
  sigemptyset(&sa.sa_mask);
  sa.sa_flags = 0;
  if (sigaction(SIGHUP, &sa, NULL) < 0)
    err_quit("%s: can't ignore SIGHUP", cmd);
  if ((pid = fork()) < 0)//最好在这里再次fork。这样使得daemon进程不再是会话首进程,那么永远没有机会获得控制终端。如果这里不fork的话,会话首进程依然可能打开控制终端。(好像不用fork二次了。。。。)
    err_quit("%s: can't fork", cmd);
  else if (pid != 0) /* parent */
    exit(0);

  /* * Change the current working directory to the root so * we won't prevent file systems from being unmounted. */
  if (chdir("/") < 0)//将当前工作目录切换到根目录。父进程继承过来的当前目录可能mount在一个文件系统上,如果不切换到根目录,那么这个文件系统不允许unmount。
    err_quit("%s: can't change directory to /", cmd);

  /* * Close all open file descriptors. */
  if (rl.rlim_max == RLIM_INFINITY)
    rl.rlim_max = 1024;
  for (i = 0; i < rl.rlim_max; i++)
    close(i);//在子进程中关闭从父进程中继承过来的那些不需要的文件描述符。可以通过_SC_OPEN_MAX来判断最高文件描述符(不是很必须).

  /* * Attach file descriptors 0, 1, and 2 to /dev/null. */
  fd0 = open("/dev/null", O_RDWR);//打开/dev/null复制到0,1,2,因为dameon进程已经和terminal脱离了,所以需要重新定向标准输入,标准输出和标准错误(不是很必须).
  fd1 = dup(0);
  fd2 = dup(0);

  /* * Initialize the log file. */
  openlog(cmd, LOG_CONS, LOG_DAEMON);
  if (fd0 != 0 || fd1 != 1 || fd2 != 2) {
    syslog(LOG_ERR, "unexpected file descriptors %d %d %d",fd0, fd1, fd2);
    exit(1);
  }
}

自己写daemon守护进程相关推荐

  1. 大神教你如何给脚本写一个守护进程

    在我们日常运维中,写脚本监控一个进程是比较常见的操作,比如我要监控mysql进程是否消失,如果消失就重启mysql. 用下面这段代码就可以实现: #!/bin/shDate=` date '+%c'` ...

  2. another mysql daemon,[守护进程详解及创建,daemon()使用

    一,守护进程概述 Linux Daemon(守护进程)是运行在后台的一种特殊进程.它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件.它不需要用户输入就能运行而且提供某种服务,不是对整个 ...

  3. c语言监控程序,C语言写监控守护进程

    C语言写监控守护进程 1.[代码][C/C++]代码 #include #include #include #include #include #include #include #include # ...

  4. linux中Daemon守护进程编程

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

  5. daemon守护进程初识

    daemon介绍 守护进程是一种生存期长的进程.常常在系统引导装载时启动,直到系统关闭时才终止.它们在后台运行,没有控制终端. daemon编写规则 1.调用umask将文件模式创建屏蔽字设置为一个已 ...

  6. daemon(守护进程)

    Daemon Daemon程序是一直运行的服务端程序,又称为守护进程.通常在系统后台运行,没有控制终端不与前台交互,Daemon程序一般作为系统服务使用.Daemon是长时间运行的进程,通常在系统启动 ...

  7. python中的daemon守护进程实现方法

    守护进程是生存期长的一种进程.它们独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件.他们常常在系统引导装入时启动,在系统关闭时终止. 守护进程的特性 1.在后台运行 2.与其运行前的环境 ...

  8. linux下daemon守护进程的实现(以nginx代码为例)

    ngx_int_t ngx_daemon(ngx_log_t *log) {int fd;// 让init进程成为新产生进程的父进程:// 调用fork函数创建子进程后,使父进程立即退出.这样,产生的 ...

  9. mysql进程daemon_守护进程详解及创建,daemon()使用

    一,守护进程概述 Linux Daemon(守护进程)是运行在后台的一种特殊进程.它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件.它不需要用户输入就能运行而 且提供某种服务,不是对整 ...

  10. python 守护程序检测进程是否存在_python创建守护进程的疑问

    我自己写了一个简易的下载和文件执行的客户端,如下 """ 省略若干代码 """ #执行下载函数 def do_script(): " ...

最新文章

  1. 进驻宝岛 不闪式3D热潮来临?
  2. Spark技术栈有哪些组件,每个组件都有什么功能,适合什么应用场景?
  3. 面试:一个Java字符串到底有多少个字符?
  4. Linux系统中如何关闭触摸鼠标
  5. [androd] android的在线源码网站,各个版本都有(目前已到俺android 4.2,但不包含kernel部分的代码)
  6. 计算器界面分析及界面程序实现
  7. TCP/IP协议簇简介
  8. 判断两个字符串是否由相同的字符组成
  9. 【转载保存】Jsoup解析html常用方法
  10. php 删除指定html标签,php删除html标签的三种解决办法
  11. 京东炸年兽活动一键做任务工具v1.7
  12. WCF 进阶: 对称加密传输
  13. python使用codecs模块进行文件操作-读写中英文字符
  14. PG修改表字段长度报错 cached plan must not change result type Hint: Please restore the result type
  15. java.lang.NumberFormatException: null原因
  16. “更新 TKK 失败,请检查网络连接” 解决方法
  17. 2021年安徽省安全员C证考试资料及安徽省安全员C证证考试
  18. 微信缓存dat怎么转图片_微信dat文件转换为图片
  19. ATI显卡配置aticonfig和amdcccle全解
  20. 【求职】有关面试和简历相关的总结与心得

热门文章

  1. 线段树相关(研究总结,线段树)
  2. 第五章 APP元素定位
  3. Zoj3762 等待解决
  4. 【转】Perl、PHP、Python、Java和Ruby的比较
  5. js获取内网ip_WebRTC安全问题:私有IP与mDNS
  6. python 框架是什么意思_Python框架有哪些?区别是什么?
  7. 开启本地git权限_git的使用,有这篇文章就够了
  8. 数据网格组件 Handsontable 不再开源,采用自拟的非商业许可证
  9. unity 录制游戏内视频(1)
  10. 模块化编程和Jigsaw项目最新早期访问版本使用教程