Linux中守护进程

简介: Linux中守护进程

守护进程运行在后台,不与任何控制终端相关联。在Linux中创建一个守护进程步骤如下:

一、调用fork创建一个子进程,父进程退出,子进程归到1号进程管理,子进程将作为守护进程。子进程是由父进程创建而来,因此,它不是进程组的首进程,这是接下来调用setsid的必要条件。

二、在子进程中通过setsid,创建一个会话(新创建的会话不会分配控制终端)。当前子进程将变为新会话的首进程以及新进程组的首进程。

man手册中setsid的介绍:

setsid()  creates  a new session if the calling process is not a process group leader.  
 The calling process is the leader of the new session, the process group leader of the new process group, and has no controlling terminal.  
The process group ID and session ID of the calling process are set to the PID of the calling process.  
The calling process will be the only process in this new process group  and  in  this new session.

三、调用chdir(),将当前工作目录改为根目录。因为守护进程是通过调用fork来创建,它继承来的当前工作目录可能在文件系统中的任何地方。而守护进程往往会在系统开机状态下一直运行,我们不希望这些随机目录一直处于打开状态,导致管理员无法卸载守护进程工作目录所在的文件系统。

四、关闭所有的文件描述符。我们不希望继承任何打开的文件描述符,不希望这些描述符一直处于打开状态而自己没有发现。

五、打开文件描述符0、1、2,并把它们重定向到/dev/null中。打开这些描述符的理由在于:守护进程调用的那些假设能从标准输入读或者往标准输出或标准错误写的库函数将不会因这些描述符未打开而失败。这种失败是一种隐患。要是一个守护进程未打开这些描述符,却作为服务器打开了与某个客户关联的一个套接字,那么这个套接字很可能占用这些描述符(譬如标准输出或标准错误输出的描述符1或2),这种情况下如果守护进程调用诸如perror之类函数,那就会把非预期的数据发送给那个客户。

代码实现:

#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/limits.h>
int main(void) {
    pid_t pid;
    pid = fork();
    if (pid == -1) 
        return -1;
    else if (pid != 0)
        exit(EXIT_SUCCESS);
    //子进程中
    if (setsid() == -1)
        return -1;
    if (chdir("/") == -1)
        return -1;
    for (int i = 0; i < NR_OPEN; i++) {
        close(i);
    }
    //重定向标准输入到 /dev/null,因为此时open返回的fd 是 0,以下同理
    open("/dev/null", O_RDONLY);
    open("/dev/null", O_RDWR);
    open("/dev/null", O_RDWR);
    return 0;
}

这时该程序便可以在后台运行了(如果是服务端程序通常都会处在一个loop中)

其实,更简单一点,我们可以直接使用daemon系统调用

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

man手册:

The daemon() function is for programs wishing to detach themselves from the controlling terminal and run in the background as system daemons.
If nochdir is zero, daemon() changes the calling process's current working directory to the root directory ("/"); otherwise, the current working directory is left unchanged.
If noclose is zero, daemon() redirects standard input, standard output and standard error to /dev/null; otherwise, no changes are made to these file descriptors.

如果参数nochdir为0,就会将该进程的工作目录改变到根目录,如果参数noclose为0,就会将标准输入、标准输出、标准错误重定位到/dev/null。因此,两个参数一般都设置为0。

相关文章
|
29天前
|
算法 Linux 调度
深入理解Linux操作系统的进程管理
本文旨在探讨Linux操作系统中的进程管理机制,包括进程的创建、执行、调度和终止等环节。通过对Linux内核中相关模块的分析,揭示其高效的进程管理策略,为开发者提供优化程序性能和资源利用率的参考。
66 1
|
17天前
|
存储 监控 Linux
嵌入式Linux系统编程 — 5.3 times、clock函数获取进程时间
在嵌入式Linux系统编程中,`times`和 `clock`函数是获取进程时间的两个重要工具。`times`函数提供了更详细的进程和子进程时间信息,而 `clock`函数则提供了更简单的处理器时间获取方法。根据具体需求选择合适的函数,可以更有效地进行性能分析和资源管理。通过本文的介绍,希望能帮助您更好地理解和使用这两个函数,提高嵌入式系统编程的效率和效果。
80 13
|
24天前
|
SQL 运维 监控
南大通用GBase 8a MPP Cluster Linux端SQL进程监控工具
南大通用GBase 8a MPP Cluster Linux端SQL进程监控工具
|
1月前
|
运维 监控 Linux
Linux操作系统的守护进程与服务管理深度剖析####
本文作为一篇技术性文章,旨在深入探讨Linux操作系统中守护进程与服务管理的机制、工具及实践策略。不同于传统的摘要概述,本文将以“守护进程的生命周期”为核心线索,串联起Linux服务管理的各个方面,从守护进程的定义与特性出发,逐步深入到Systemd的工作原理、服务单元文件编写、服务状态管理以及故障排查技巧,为读者呈现一幅Linux服务管理的全景图。 ####
|
2月前
|
缓存 监控 Linux
linux进程管理万字详解!!!
本文档介绍了Linux系统中进程管理、系统负载监控、内存监控和磁盘监控的基本概念和常用命令。主要内容包括: 1. **进程管理**: - **进程介绍**:程序与进程的关系、进程的生命周期、查看进程号和父进程号的方法。 - **进程监控命令**:`ps`、`pstree`、`pidof`、`top`、`htop`、`lsof`等命令的使用方法和案例。 - **进程管理命令**:控制信号、`kill`、`pkill`、`killall`、前台和后台运行、`screen`、`nohup`等命令的使用方法和案例。
153 4
linux进程管理万字详解!!!
|
2月前
|
缓存 算法 Linux
Linux内核的心脏:深入理解进程调度器
本文探讨了Linux操作系统中至关重要的组成部分——进程调度器。通过分析其工作原理、调度算法以及在不同场景下的表现,揭示它是如何高效管理CPU资源,确保系统响应性和公平性的。本文旨在为读者提供一个清晰的视图,了解在多任务环境下,Linux是如何智能地分配处理器时间给各个进程的。
|
2月前
|
存储 运维 监控
深入Linux基础:文件系统与进程管理详解
深入Linux基础:文件系统与进程管理详解
90 8
|
2月前
|
网络协议 Linux 虚拟化
如何在 Linux 系统中查看进程的详细信息?
如何在 Linux 系统中查看进程的详细信息?
158 1
|
2月前
|
Linux
如何在 Linux 系统中查看进程占用的内存?
如何在 Linux 系统中查看进程占用的内存?
|
2月前
|
算法 Linux 定位技术
Linux内核中的进程调度算法解析####
【10月更文挑战第29天】 本文深入剖析了Linux操作系统的心脏——内核中至关重要的组成部分之一,即进程调度机制。不同于传统的摘要概述,我们将通过一段引人入胜的故事线来揭开进程调度算法的神秘面纱,展现其背后的精妙设计与复杂逻辑,让读者仿佛跟随一位虚拟的“进程侦探”,一步步探索Linux如何高效、公平地管理众多进程,确保系统资源的最优分配与利用。 ####
75 4