头图

1. 概念

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

2. 模型

2.1 守护进程编程步骤

  1. 创建子进程,父进程退出 所有工作在子进程中进行:形式上脱离了控制终端;
  2. 在子进程中创建新会话 setsid()函数,使子进程完全独立出来,脱离控制;
  3. 改变当前目录为根目录 chdir()函数:防止占用可卸载的文件系统 也可以换成其它路径;
  4. 重设文件权限掩码:umask()函数 防止继承的文件创建屏蔽字拒绝某些权限 增加守护进程灵活性;
  5. 关闭文件描述符:继承的打开文件不会用到,浪费系统资源,无法卸载;
  6. 开始执行守护进程核心工作;
  7. 守护进程退出处理。

2.2 代码模型

#include <stdlib.h> 
#include <stdio.h> 
#include <fcntl.h>
void daemonize(void)
{
    pid_t pid;
    /*
     * 成为一个新会话的首进程,失去控制终端 
     */
     if ((pid = fork()) < 0) { 
         perror("fork");
        exit(1);
        } else if (pid != 0) /* parent */
            exit(0); 
        setsid();
    /*
     * 改变当前工作目录到/目录下. 
     */
    if (chdir("/") < 0) { 
        perror("chdir"); 
        exit(1);
    }
    /* 设置umask为0 */ 
    umask(0);
    //重定向0,1,2文件描述符到 /dev/null,因为已经失去控制终端,再操作0,1,2没有意义.
    close(0); 
    open("/dev/null", O_RDWR); 
    dup2(0, 1);
    dup2(0, 2);
}
int main(void) {
    daemonize(); 
    while(1);
    /* 在此循环中可以实现守护进程的核心工作 */
}

运行这个程序,它变成一个守护进程,不再和当前终端关联。用ps命令看不到,必须运 行带x参数的ps命令才能看到。另外还可以看到,用户关闭终端窗口或注销也不会影响守护 进程的运行。

3. 守护进程作用

守护进程为什么要和控制终端脱离?

之所以脱离于终端是为了避免进程被任何终端所产生的信息所打断,其在 执行过程中的信息也不在任何终端上显示。由于在 linux 中,每一个系统与用户进行交流的界面称为终端,每一个从此终端开始运行的进程都会依
附于这个终端,这个终端就称为这些进程的控制终端,当控制终端被关闭时,相应的进程都会自动关闭。但是我们很多应用程序不希望关闭中断就退出进程,比如说数据库、Web服务、游戏服务等,这个时候就需要用到守护进程。

4.总结

本文介绍了守护进程的概念,守护进程的编程步骤,代码实现,以及守护进程的作用。帮助我们理解后台程序的运行原理等。


轻口味
16.9k 声望3.9k 粉丝

移动端十年老人,主要做IM、音视频、AI方向,目前在做鸿蒙化适配,欢迎这些方向的同学交流:wodekouwei