Linux之守护进程详解

 更新时间:2025年05月26日 10:40:06   作者:s_little_monster_  
这篇文章主要介绍了Linux之守护进程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

一、守护进程的概念

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

守护进程是 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 值,则不进行重定向

三、进程属性信息

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都一样

同一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(STDIN_FILENO);
    close(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); // 模拟工作
    }

    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;
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • linux中Centos7增加swap分区详解

    linux中Centos7增加swap分区详解

    本篇文章给大家详细讲解了linux中Centos7增加swap分区的方法以及注意点,需要的朋友学习下。
    2018-02-02
  • LNMP下添加Discuz x2.5的伪静态规则

    LNMP下添加Discuz x2.5的伪静态规则

    今天一个找我配置过 lnmp 环境的用户要搭建 Discuz 论坛,但是发现不支持伪静态,倡萌没怎么折腾过 Discuz,百度下才知道,原来军哥的 LNMP 环境包自带的 DZ 规则不适用于 Discuz x2.5,记录下对应的伪静态规则
    2016-09-09
  • linux并发连接50万的配置方法

    linux并发连接50万的配置方法

    这篇文章主要介绍了linux并发连接50万的配置方法,需要的朋友可以参考下
    2016-08-08
  • CentOS 服务器安全配置策略

    CentOS 服务器安全配置策略

    近期服务器频繁有被暴力破解,大致分析了一下入侵行为,整理了常用的安全策略,需要的朋友可以参考下
    2019-11-11
  • 宝塔Linux面板 2.8.9稳定版介绍

    宝塔Linux面板 2.8.9稳定版介绍

    这篇文章主要介绍了宝塔Linux面板 2.8.9稳定版介绍,需要的朋友可以参考下
    2017-04-04
  • 5个可能被你忽略的Linux安全设置方法

    5个可能被你忽略的Linux安全设置方法

    众所周知,网络安全是一个非常重要的课题,而服务器是网络安全中最关键的环节。Linux被认为是一个比较安全的Internet服务器,作为一种开放源代码操作系统,一旦Linux系统中发现有安全漏洞,Internet上来自世界各地的志愿者会踊跃修补它。
    2008-09-09
  • 深入理解linux下查看进程内存的使用情况

    深入理解linux下查看进程内存的使用情况

    本篇文章是对linux下查看进程内存的使用情况进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • CentOS7系统增加swap的操作方法实例

    CentOS7系统增加swap的操作方法实例

    这篇文章主要给大家介绍了关于CentOS7系统增加swap的操作方法,文中通过示例代码介绍的非常详细,对大家的学习或者使用CentOS7系统具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-10-10
  • linux日志轮询方案

    linux日志轮询方案

    Linux系统中的日志文件会随时间增长,手动清理较为繁琐,logrotate程序可自动执行日志文件的轮换、压缩、删除和邮件发送,节省磁盘空间,logrotate基于crontab运行,调用配置文件/etc/logrotate.conf,用户可在/etc/logrotate.d目录放置自定义配置文件
    2024-10-10
  • linux中如何添加用户并赋予root权限详解

    linux中如何添加用户并赋予root权限详解

    这篇文章主要先是给大家介绍了linux中如何添加用户并赋予root权限,而后有详细的介绍了Linux系统用户组的管理,文中通过示例代码介绍的很详细,相信对大家的理解和学习具有一定的参考借鉴价值,有需要的朋友们下面来一起学习学习吧。
    2016-11-11

最新评论