开发者

Linux之守护进程详解

开发者 https://www.devze.com 2025-05-27 09:59 出处:网络 作者: s_little_monster_
目录一、守护进程的概念二、调用接口1、创建新会话2、守护进程三、进程属性信息四、深入理解守护进程1、实现过程2、实例总结一、守护进程的概念
目录
  • 一、守护进程的概念
  • 二、调用接口
    • 1、创建新会话
    • 2、守护进程
  • 三、进程属性信息
    • 四、深入理解守护进程
      • 1、实现过程
      • 2、实例
    • 总结

      一、守护进程的概念

      我们在前面的博文《进程信号的产生》中提到过前台进程和后台进程的概念,它们之间的区别就是是否获得键盘文件,拥有键盘输入的就是前台进程,后台进程获取不到键盘文件

      守护进程是 linux 系统中运行在后台的特殊进程,具有无终端依赖、长期运行、权限分离等特点,通常用于实现系统服务、网络服务等功能,进行守护进程化的进程就是将终端关闭也不会杀死,只要服务器一直运行,它就可以一直运行,但可以通过kill命令杀死

      二、调用接口

      1、创建新会话

      #include <unistd.h>
      pid_t setsid(void);

      返回值:成功返回新会话id,失败返回-1

      2、守护进程

      #include <unistd.h>
      int daemon(int nochdir, int noclose);

      返回值:成功返回0,失败返回-1

      • nochdir:如果该参数的值为 0,daemon 函数会将当前工作目录更改为根目录(/),如果为非 0 值,则不更改当前工作目录
      • noclose:如果该参数的值为 0,daemon 函数会将标准输入、标准输出和标准错误输出重定向到 /dev/null,如果为非 0 值,则不进行重定向

      三、进程属性信息

      Linux之守护进程详解

      1. PPID(Parent Process ID)

      • 全称:父进程ID
      • 含义:当前进程的父进程的唯一标识符
      • 作用:用于跟踪进程间的父子关系(例如,通过fork()创建的子进程会继承父进程的PPID)

      2. PID(Process ID)

      • 全称:进程ID
      • 含义:操作系统分配给每个进程的唯一数字标识符(范围通常为1~32768)
      • 作用:用于区分和管理系统中的不同进程(例如,通过kill命令终止进程)

      3. PGID(Process Group ID)

      • 全称:进程组ID
      • 含义:进程所属的进程组的ID,进程组是一个或多个相关进程的集合,一个任务对应一个进程组
      • 作用:便于批量管理相关进程(如停止或恢复整个进程组)

      4. SID(Session ID)

      • 全称:会话ID
      • 含义:进程所属的会话的ID,会话由一个或多个进程组组成,通常由登录 shell 创建,实际上是bashid
      • 作用:管理终端会话中的所有进程(例如,当用户注销时,整个会话的进程会被终止)

      5. TTY(Teletypewriter)

      • 全称:终端设备
      • 含义:进程关联的终端设备(如pts/0表示伪终端),若显示为?,表示进程无控制终端
      • 作用:区分进程是否在终端中运行(如后台服务通常无终端)

      6. TPGID(Foreground Process Group ID)

      • 全称:前台进程组ID
      • 含义:当前在终端前台运行的进程组的ID
      • 作用:终端输入/输出会被分配给前台进程组(例如,按Ctrl+C会中断前台进程)

      7. STAT(Process Status)

      全称:进程状态

      含义:进程的当前状态,常见状态码包括:

      • R(运行中)
      • S(睡眠中)
      • D(不可中断睡眠)
      • T(停止)
      • Z(僵尸进程)

      作用:快速判断进程的运行状态(例如,Z表示进程已终止但未被父进程回收)

      8. UID(User ID)

      • 全称:用户ID
      • 含义:启动进程的用户的唯一标识符(如root的UID为0)
      • 作用:用于权限控制(例如,普通用户无法修改root进程)

      9. TIME

      • 全称:CPU时间
      • 含义:进程自启动以来累计使用的CPU时间(格式为HH:MM:SS
      • 作用:衡量进程对CPU资源的占用情况

      10. COMMAND

      • 全称:命令名称
      • 含义:启动进程的命令或程序名称(如bashnginx
      • 作用:快速识别进程的功能(例如,通过COMMAND列判断是否为恶意程序)

      同一个session内启动的sid都一样android

      同一PGID的,即一个组内的,PIDPGID相同的被称为组长

      四、深入理解守护进程

      1、实现过程

      首先创建子进程然后退出父进程,使子进程在后台运行,然后创建新会话,脱离掉原会话和控制终端,保证进程不受终端信号影响,然后再重定向标准输入输出,确保守护进程不与终端交互,然后变更工作目录,忽略掉子进程退出信号和终端停止信号,所以守护进程本质上是一个孤儿进程

      2、实例

      #include <unistd.h>
      #include <sys/types.h>
      #include <fcntl.h>
      #include <syslog.h>
      
      void daemonize() {
          // 创建子进程并退出父进程,子进程成为孤儿进程
          pid_t pid = fork();
          if (pid < 0) exit(EXIT_FAILURE);
          if (pid > 0) exit(EXIT_SUCCESS);
      
          // 创建新会话,调用该函数的进程会成为新会话的会话首进程、新进程组的组长进程
          //并且会脱离原有的控制终端
          if (setsid() == -1) exit(EXIT_FAILURE);
      
          // 重定向标准输入输出
          close(SphpTDIN_FILENO);
          clos编程e(STDOUT_FILENO);
          close(STDERR_FILENO);
          int fd = open("/dev/null", O_RdwR);
          dup2(fd, STDIN_FILENO);
          dup2(fd, STDOUT_FILENO);
          dup2(fd, STDERR_FILENO);
      
          // 允许所有权限
          umask(0);
      
          // 变更工作目录
          chdir("/");
      
          // 忽略子进程状态改变时发送给父进程的信号
          signal(SIGCHLD, SIG_IGN);
      }
      
      int main() {
          daemonize();
          while (1) {
              sleep(3600); // android模拟工作
          }
      
          return 0;
      }

      上面的过程,可以被函数daemon函数替换

      #include <unistd.h>
      #include <syslog.h>
      
      int main() {
          // 使用 daemon 函数将当前进程转换为守护进程
          // 第一个参数 0 表示将工作目录更改为根目录
          // 第二个参数 0 表示将标编程客栈准输入、标准输出和标准错误输出重定向到 /dev/null
          if (daemon(0, 0) == -1) {
              perror("daemon");
              return 1;
          }
          // 模拟守护进程持续工作
          while (1) {
              // 睡眠 3600 秒(1 小时)
              sleep(3600); 
          }
      
          return 0;
      }

      总结

      以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程客栈(www.devze.com)。

      0

      精彩评论

      暂无评论...
      验证码 换一张
      取 消

      关注公众号