当前位置: 首页 > news >正文

Linux网络:守护进程

文章目录

  • 前言
  • 一,会话和进程组
    • 1-1 会话的定义
    • 1-2 进程组的定义
    • 1-3 进程组和会话的区别
  • 二,守护进程
    • 2-1 setsid
    • 2-2 daemon


前言

什么是守护进程?

  • 守护进程是 Linux 里在后台运行的程序,不跟用户直接互动(没界面),悄悄提供服务。它们脱离终端(TTY 是 ?),通常系统启动就运行,直到关机。

  • 比喻:守护进程像餐厅的“隐形帮手”(比如自动洗碗机或空调)。你吃饭时不用管它们,但它们让餐厅(系统)正常运转。

  • 当我们关闭终端会话(比如退出 SSH 或关闭终端窗口)时,终端会关闭,与该会话关联的前台进程会终止,后台进程也可能因收到 SIGHUP 信号而终止,但服务器本身仍在运行。如果我们希望某些进程在会话关闭后继续运行,可以使用守护进程(daemon),它通过创建新会话(setsid)脱离终端,适合长期运行的服务

一,会话和进程组


1-1 会话的定义

  • 会话Linux 中一组相关进程的集合,通常与一个终端(比如你打开的 Ubuntu 终端窗口 pts/0SSH 连接)绑定。
  • 每个会话有唯一的会话 ID(SID),由会话的第一个进程(会话领导者)的进程 ID(PID)决定。
  • 会话里的进程通常一起工作,比如你运行一个命令(ls | grep txt)lsgrep这些进程属于同一个会话。

比喻:

会话像餐厅的一个“工作小组”,由一个“组长”(会话领导者,比如 bash)带领。小组里的成员(进程)一起干活,组长负责和餐厅前台(终端)沟通。如果前台关门(终端关闭),整个小组通常会解散(进程终止)。

作用:

  • 组织进程:把相关的进程(比如一个命令涉及的多个进程)归到一起,方便管理。
  • 终端控制:会话通常与终端关联,控制输入/输出(比如键盘输入、屏幕显示)。
  • 信号传递:当终端关闭时,会话中的进程会收到 SIGHUP 信号,通常导致终止。

在这里插入图片描述

像在xshell这里的这个新建会话就是新建一个bash,如果退出bash那么这个bash下的进程都会退出,或者我们后续在bash中通过setsid创建会话

root@hcss-ecs-f59a:~# ps -jPID    PGID     SID TTY          TIME CMD52589   52589   52589 pts/0    00:00:00 bash52990   52990   52589 pts/0    00:00:00 sleep52991   52991   52589 pts/0    00:00:00 sleep52992   52992   52589 pts/0    00:00:00 ps

像在这里的SID相同的就是该会话bash下的进程


1-2 进程组的定义

进程组是由一个或多个进程构成的,每个进程组有唯一的进程组 ID(PGID),通常由组内第一个进程(进程组领导者)的 PID 决定。

进程组中的进程通常一起工作,比如执行一个命令或管道(ls | grep txt),共享同一个 PGIDlsgrep都是一个独立的进程,将它们规定在一个进程组织,实现整体效果

作用:

  • 统一管理:Linux 可以给整个进程组发送信号(如 Ctrl+C 终止所有相关进程)

  • 终端控制:进程组决定哪些进程是前台(接受键盘输入)或后台(用 & 运行)

  • 组织相关任务:比如管道命令的多个进程组成一个进程组

sleep 200 &
[1] 48062
root@hcss-ecs-f59a:~# sleep 300 &
[2] 48074
root@hcss-ecs-f59a:~# sleep 400 &
[3] 48075

这里我们运行三个进程,在后台休眠200秒,300秒,400秒

查看进程

root@hcss-ecs-f59a:~# ps -jPID    PGID     SID TTY          TIME CMD47807   47807   47807 pts/0    00:00:00 bash48062   48062   47807 pts/0    00:00:00 sleep48074   48074   47807 pts/0    00:00:00 sleep48075   48075   47807 pts/0    00:00:00 sleep48153   48153   47807 pts/0    00:00:00 ps
  • SID:每个进程有一个 SID,表示它属于哪个会话(一组相关进程的集合)。

  • bash:这是你的终端 shell(命令行解释器),通常是会话的领导者,它的进程 ID(PID)等于会话的 SID

  • SIDbash 相同说明:该进程属于当前终端的会话,即它和 bash 在同一个“工作小组”中,这个进程受当前终端控制,它可以访问终端的输入/输出(键盘、屏幕),但如果关闭终端,会话结束,进程可能会收到 SIGHUP 信号而终止。

简单说:进程“还在终端的管辖范围内”,像一个“团队成员”,跟着 bash(组长)一起工作


1-3 进程组和会话的区别

会话构成:会话是由一个或多个进程组构成的,通常与一个终端(如 pts/0SSH 连接)绑定,每个会话有一个会话领导者,通常是启动会话的进程(比如 bash),其 PID(进程 ID)等于SID(会话 ID),会话中的所有进程组共享同一个 SIDSID 由会话领导者的 PID 决定

进程组构成:进程组是由一个或多个进程构成的,每个进程组有唯一的进程组 ID(PGID),通常由组内第一个进程(进程组领导者)的 PID 决定。进程组中的进程通常一起工作,比如执行一个命令或管道(ls | grep txt),共享同一个 PGID

比喻:
会话是大团队(由 bash 领导,SID = bash PID),进程组是小分队(由一个进程领导,PGID = 其 PID),大团队(会话)包含多个小分队(进程组),小分队由队员(进程)组成

你的终端会话(SID=35415,bash 的 PID)可能包含

  • 进程组 1:运行 ls | grep txt(PGID=36133,包含 ls 和 grep)。
  • 进程组 2:运行 sleep 200 &(PGID=36135,包含 sleep)。

setsid sleep 200 &,创建一个新会话(SID=36132),包含一个进程组(PGID=36132,只有一个进程 sleep)。


二,守护进程

守护进程的特点:脱离终端(不会因为用户退出而结束),独立于用户会话,不受终端控制,可以长期在后台运行。

当会话退出时,也就是当我们关闭xshell关闭了我们的bash,我们的会话也就结束了,那么会话当前下的进程组也就结束了,如果我们不想关闭xshellbash就关闭的话我们可以选择使用setsid或则daemon新建一个会话来执行这个进程组


2-1 setsid

setsid() 是一个系统调用,用来 创建一个新的会话,并让调用进程成为这个新会话的首进程

函数原型(在 <unistd.h> 里):

pid_t setsid(void);

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

演示代码

#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <cstdlib>int main() {pid_t pid = fork();if (pid < 0) {std::cerr << "fork failed" << std::endl;exit(1);}if (pid > 0) {// 父进程直接退出std::cout << "Parent exit, child PID: " << pid << std::endl;exit(0);}// 改变当前目录(可选,防止占用挂载点)chdir("/");// 关闭标准输入输出(可选)close(STDIN_FILENO);close(STDOUT_FILENO);close(STDERR_FILENO);// 守护进程的核心逻辑while (true) {int fd = open("/tmp/daemon.log", O_WRONLY | O_CREAT | O_APPEND, 0644);if (fd >= 0) {std::string msg = "Daemon is alive, PID: " + std::to_string(getpid()) + "\n";write(fd, msg.c_str(), msg.size());close(fd);}sleep(5); // 每隔 5 秒写一次}return 0;
}

重点讲解:在这里我们实现了一个进程,不断向/tmp/daemon.log中打印数据。

在这里我们将进程的工作路径重定向到/根目录中,是为了防止工作目录被删除,进程工作丢失,其它的代码不过多讲解

setsid():让子进程创建一个新的会话,成为会话首进程,脱离控制终端


2-2 daemon

setsid() 是用来创建新会话、脱离终端的底层系统调用,通常需要配合 fork()chdir("/")、关闭文件描述符等步骤才能完整实现守护进程;而 daemon() 是对这些步骤的封装,调用后可自动完成会话创建、切换目录、重定向文件描述符等操作,更方便但灵活性较低

函数声明:

#include<unistd.h>
int daemon(int nochdir, int noclose)
  • nochdir:改变工作目录
    • 传入0:改变工作目录为根目录
    • 传入1:保持当前工作目录
  • nclose:改变输入输出流
    • 传入0:输入输出流重定向到/dev/null
    • 传入1:不改变输入输出流

演示代码

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>int main() {// 创建守护进程if (daemon(0, 0) == -1) {perror("daemon error");exit(1);}FILE *fp;while (1) {fp = fopen("/tmp/daemon_test.log", "a+");if (fp) {time_t t = time(NULL);fprintf(fp, "Daemon is running at: %s", ctime(&t));fclose(fp);}sleep(5); // 每隔5秒写一次日志}return 0;
}

这里我们也是创建了一个脱离bash的会话,但是我们的daemon封装了setsidchdirfork


文章转载自:

http://jyfq8Xuo.rfdqr.cn
http://ismc4fOV.rfdqr.cn
http://nvdrS00z.rfdqr.cn
http://tVYjsodE.rfdqr.cn
http://JmLw6SGs.rfdqr.cn
http://ipO17pp8.rfdqr.cn
http://8A8IpcPa.rfdqr.cn
http://jpn0ijyd.rfdqr.cn
http://clgsHbYF.rfdqr.cn
http://EoiaBddY.rfdqr.cn
http://EddZcmVH.rfdqr.cn
http://QLdfZLL9.rfdqr.cn
http://hXLfPh0b.rfdqr.cn
http://97MxPu03.rfdqr.cn
http://buMjW98s.rfdqr.cn
http://q1mTuSbx.rfdqr.cn
http://j0CRg2SA.rfdqr.cn
http://h3nPFijI.rfdqr.cn
http://qlaKpp1y.rfdqr.cn
http://YoMV3EfA.rfdqr.cn
http://Bqg6bs32.rfdqr.cn
http://JWqHCG3m.rfdqr.cn
http://YkPJrTOq.rfdqr.cn
http://k58chGs4.rfdqr.cn
http://1WEnCKX0.rfdqr.cn
http://m5LuvfxS.rfdqr.cn
http://GANB7J6Z.rfdqr.cn
http://pvZ25chV.rfdqr.cn
http://HulxmNGd.rfdqr.cn
http://PZHrx9ro.rfdqr.cn
http://www.dtcms.com/a/386506.html

相关文章:

  • 用C语言求数组Sn的前5项
  • 物联网传感器检测实验
  • GTA式送货!新游《Deliver At All Costs》上线steam
  • 亚马逊新品优化全攻略:从冷启动到高转化的系统化路径
  • 基于属性描述转移的高压断路器零样本智能诊断模型
  • C2(Command Control)命令与控制
  • Tessent_ijtag_ug——第 5 章IJTAG 网络插入 (2)
  • Kaggle铜牌攻略:从泰坦尼克到房价预测,数据科学竞赛完整流程解析
  • 结合图像-文本信息与特征解纠缠的多标签广义零样本胸部X射线分类|文献速递-最新医学人工智能文献
  • JavaScript数组some()和every()方法
  • 全球炭黑复合导电浆料市场报告:原材料波动与技术创新的双重博弈
  • 自动为wordpress外贸网站设置一个标题图
  • 【大模型记忆-Mem0详解-6】核心组件-图形记忆
  • Ansys Zemax | 如何使用极探测器和 IESNA / EULUMDAT 光源数据
  • 【记录】初赛复习 Day2 Day3(内附2024S第一轮难题详解)
  • 洛谷 闰年求和 简单模板题
  • 【Sa-Token 中 三种Session会话 模型详解】
  • MacOS M1安装face_recognition
  • 鸿蒙应用冷启动优化:本地 KV 缓存预热实战指南
  • glib2-2.62.5-7.ky10.x86_64.rpm怎么安装?Kylin Linux RPM包安装详细步骤
  • 少儿舞蹈小程序(16)购物车功能开发
  • 【Node】Windows安装node多版本管理工具nvm
  • JAVA上门家政维修服务系统源码微信小程序+微信公众号+APP+H5
  • Linux学习笔记(五)--Linux基础开发工具使用
  • pyspark自定义udf函数
  • SpringBoot MySQL
  • 【GOTO判断素数输出孪生10对】2022-11-14
  • 【STL库】哈希表的原理 | 哈希表模拟实现
  • A股大盘数据-20250916分析
  • mysql 获取时间段之间的差值