Linux:守护进程(进程组、会话和守护进程)

守护进程(Daemon)是 Linux 系统中一种长期运行的后台进程,通常用于执行系统级别的任务或服务。理解守护进程涉及进程组、会话及其与其他进程的关系。本文将详细介绍这些概念及其在 Linux 中的应用。

一、进程组(Process Group)

进程组是一个或多个进程的集合,用于信号传递和终端输入输出控制。进程组中的每个进程都有一个相同的进程组 ID(PGID),PGID 等于进程组组长的进程 ID(PID)。

1. 创建进程组

当一个进程创建新进程时,默认情况下新进程继承其父进程的 PGID。可以通过调用 setpgid 函数来改变进程的 PGID。

复制代码
#include <unistd.h>
#include <stdio.h>

int main() {
    pid_t pid = fork();

    if (pid == 0) {
        // 子进程
        setpgid(0, 0); // 创建新的进程组
        printf("Child process PGID: %d\n", getpgid(0));
    } else {
        // 父进程
        printf("Parent process PGID: %d\n", getpgid(0));
    }

    return 0;
}
2. 查看进程组

可以使用 ps 命令查看进程的 PGID:

复制代码
ps -o pid,pgid,cmd
二、会话(Session)

会话是一个或多个进程组的集合。会话由一个会话首领进程创建,该进程成为会话的领导者,并且它的 PID 就是会话 ID(SID)。会话首领进程可以通过调用 setsid 函数创建一个新的会话。

1. 创建会话

创建一个新的会话,将当前进程变为会话领导者:

复制代码
#include <unistd.h>
#include <stdio.h>

int main() {
    pid_t sid = setsid(); // 创建新的会话
    if (sid == -1) {
        perror("setsid");
        return 1;
    }
    printf("Session ID: %d\n", sid);
    return 0;
}
2. 查看会话

可以使用 ps 命令查看进程的 SID:

复制代码
ps -o pid,sid,cmd
三、守护进程(Daemon)

守护进程是一种在后台运行的进程,通常由系统启动脚本或其他服务管理工具启动。守护进程脱离控制终端,独立于用户的会话。

1. 创建守护进程

创建守护进程的一般步骤包括:

  1. 创建子进程,终止父进程:确保守护进程不是会话领导者,防止它重新打开控制终端。
  2. 创建新的会话:使守护进程成为新会话的领导者。
  3. 改变工作目录:通常将工作目录更改为根目录,以防止锁定任何挂载的文件系统。
  4. 重设文件权限掩码:防止继承父进程的文件权限。
  5. 关闭文件描述符:关闭继承的文件描述符。

下面是一个创建守护进程的示例代码:

复制代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>

void daemonize() {
    pid_t pid;

    // 创建子进程
    pid = fork();
    if (pid < 0) {
        exit(EXIT_FAILURE);
    }
    if (pid > 0) {
        exit(EXIT_SUCCESS); // 父进程退出
    }

    // 创建新的会话
    if (setsid() < 0) {
        exit(EXIT_FAILURE);
    }

    // 捕获、忽略 SIGHUP 信号
    signal(SIGHUP, SIG_IGN);

    // 创建新子进程,终止父进程,防止重新获得控制终端
    pid = fork();
    if (pid < 0) {
        exit(EXIT_FAILURE);
    }
    if (pid > 0) {
        exit(EXIT_SUCCESS);
    }

    // 改变工作目录
    if (chdir("/") < 0) {
        exit(EXIT_FAILURE);
    }

    // 重设文件权限掩码
    umask(0);

    // 关闭文件描述符
    close(STDIN_FILENO);
    close(STDOUT_FILENO);
    close(STDERR_FILENO);
}

int main() {
    daemonize();

    // 守护进程的主循环
    while (1) {
        // 执行后台任务
        sleep(30); // 示例:每隔30秒执行一次任务
    }

    return EXIT_SUCCESS;
}
四、管理守护进程
1. 使用 systemd

现代 Linux 系统通常使用 systemd 管理守护进程。可以创建一个 systemd 服务文件来管理守护进程。

创建一个示例服务文件 /etc/systemd/system/mydaemon.service

复制代码
[Unit]
Description=My Daemon Service

[Service]
ExecStart=/usr/local/bin/mydaemon
Restart=always
User=nobody
Group=nobody

[Install]
WantedBy=multi-user.target

然后启用并启动服务:

复制代码
sudo systemctl enable mydaemon
sudo systemctl start mydaemon
​
2. 使用 init.d

在旧版 Linux 系统中,可以使用 init.d 脚本管理守护进程。创建一个示例脚本 /etc/init.d/mydaemon

复制代码
#!/bin/sh

### BEGIN INIT INFO
# Provides:          mydaemon
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: My Daemon Service
### END INIT INFO

case "$1" in
    start)
        echo "Starting mydaemon"
        /usr/local/bin/mydaemon &
        ;;
    stop)
        echo "Stopping mydaemon"
        pkill mydaemon
        ;;
    restart)
        $0 stop
        $0 start
        ;;
    *)
        echo "Usage: $0 {start|stop|restart}"
        exit 1
esac

exit 0

然后启用并启动服务:

复制代码
sudo chmod +x /etc/init.d/mydaemon
sudo update-rc.d mydaemon defaults
sudo service mydaemon start
相关推荐
想躺在地上晒成地瓜干1 小时前
树莓派超全系列教程文档--(57)如何设置 Apache web 服务器
服务器·apache·树莓派·raspberrypi·树莓派教程
Linux运维技术栈1 小时前
Vim 命令大全:从入门到精通
linux·编辑器·vim
c7_ln1 小时前
Linux基本指令(包含vim,用户,文件等方面)超详细
linux·操作系统·vim
苹果醋32 小时前
AI大模型竞赛升温:百度发布文心大模型4.5和X1
java·运维·spring boot·mysql·nginx
晨曦backend2 小时前
Vim 撤销 / 重做 / 操作历史命令汇总
linux·编辑器·vim
晨曦backend2 小时前
Vim 插件管理:MiniBufExplorer 使用指南
linux·编辑器·vim
fatiaozhang95273 小时前
中兴B860AV1.1_晨星MSO9280芯片_4G和8G闪存_TTL-BIN包刷机固件包
android·linux·adb·电视盒子·av1·魔百盒刷机
froxy3 小时前
Panthor 开源方案与 Mesa 图形库的技术解析
linux·开源
nice_evil3 小时前
华为Openeuler/Linux/CentOs 网络配置及故障排查/远程连接设置ssh/ibmc等问题及解决方案合集
linux·网络·centos·openeuler·网络配置与激活
liulilittle3 小时前
OpenSSL 的 AES-NI 支持机制
linux·运维·服务器·算法·加密·openssl·解密