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

【Linux网络编程】之守护进程

【Linux网络编程】之守护进程

  • 进程组
    • 进程组的概念
    • 组长进程
  • 会话
    • 会话的概念
    • 会话ID
  • 控制终端
    • 控制终端的概念
    • 控制终端的作用
    • 会话、终端、bash三者的关系
  • 前台进程与后台进程
    • 概念
    • 特点
    • 查看当前终端的后台进程
    • 前台进程与后台进程的切换
  • 作业控制
    • 相关概念
    • 作业状态(一般指后台作业)
  • 守护进程
    • 概念
    • 将进程守护化
      • 进程守护化的步骤
      • 代码实现

进程组

进程组的概念

当我们使用以下命令查与进程相关的属性时,会看到一个叫PGID的属性:

ps ajx

image-20250207143545861

它标识某一个进程属于哪个进程组。

进程组是一个进程或者多个进程的集合。每一个进程组有唯一的PGID,它是一个正整数,和PPIDPID一样,可以在C语言中用pid_t类型表示。

例如,在终端中执行如下命令:

sleep 1000 | sleep 2000 | sleep 3000

使用ps查看:

ps ajx | head -1 && ps ajx | grep -v 'grep' | grep sleep

img

这三个进程的PPID也就是父进程都是一样的,也就是-bash进程,所以这三个sleep进程是兄弟进程,它们同属于一个进程组。

image-20250207144949286

就算只有一个进程,它也会自成一个进程组:

image-20250207145100828

组长进程

组长进程就是进程组中的第一个创建的进程(按照时间),如果这个进程组中就只有一个进程,那么它就是进程组中的组长。

当进程组中的组长终止后,这个进程组并不会终止,要等到这个进程组中的最后一个进程终止,它才会终止。

代码验证1:使用下面代码先验证,C语言fork子进程,父进程和子进程属于一个进程组,且父进程是组长进程。

#include<stdio.h>
#include<unistd.h>
int main()
{pid_t id = fork();if(id == 0)//子进程执行{while(1){printf("i am child,my pid is %d\n",getpid());sleep(1);}}while(1);return 0;
}

运行结果:

image-20250207150717602

代码验证2:当组长进程结束,进程组并不会立即终止,而是等这个组中所有的进程终止后再终止:

#include<stdio.h>
#include<unistd.h>
int main()
{pid_t id = fork();if(id == 0)//子进程执行{while(1){printf("i am child,my pid is %d\n",getpid());sleep(1);}}return 0;
}

运行结果:

image-20250207151249008

会话

会话的概念

会话可以看作是多个进程组的集合,一个会话会有多个进程组,会话也会有唯一的会话ID。

一般来说,会话中的第一个进程组是-bash对应的进程组,会话ID等于该-bash进程组的组ID。

image-20250207153415886

通常来说,进程组可以由以下方式创建:

  1. 通过管道创建兄弟进程,这些兄弟进程是一个进程组
  2. 父进程fork子进程,父子进程是一个进程组。

会话ID

上面我们提到了会话ID,会话ID就是该会话中首进程的进程ID或者说是首进程的组ID。(就是-bash进程的进程ID,-bash进程总是会首进程,也是会首进程的组长进程)。

控制终端

控制终端的概念

在Linux/类Uinx系统中,控制终端通常与会话关联。即一个会话对应一个控制终端

当用户通过一个终端登录系统,会得到一个首进程shell进程,这个终端成为shell进程的控制终端,由于有关控制终端的信息存储在进程PCB中,后续的其它进程都是通过shell进程fork的,所以其它进程的控制终端也都是这个控制终端。

实际上控制终端是一个逻辑概念,每个控制终端都对应一个终端文件。这些文件被称为终端文件tty设备文件

Linux中,终端文件在/dev/pts路径下:

ls /dev/pts

实验验证:实验步骤如下。

  1. 终端1,循环执行以下脚本指令:

     while :;do ls -l /dev/pts;sleep 1;echo "~~~~~~~~~~~~~~~~~";done
    
  2. 不断创建新的终端,观察打印的终端文件是否增多。

  3. 关闭打开的终端,观察打印的终端文件是否减少。

实验现象如下:

屏幕录制-2025-02-07-172050

控制终端的作用

  1. 信号发送:可以通过特定的组合键向前台进程组发送信号,比如Ctrl+C发送SIGINT信号来中断当前操作,或者Ctrl+Z发送SIGTSTP暂停一个进程。

  2. 输入输出:控制终端为进程提供标准输入、输出和错误流。大多数情况下,这些流直接对应于用户的键盘输入和屏幕显示。

    • 什么意思呢,就是我们向键盘输入一个内容都会显示在控制终端上,printf等往显示器打印的函数,打印的内容也会显示到终端上。因为**当进程启动时,如果没有特别指定其他的输入输出目的地(重定向),其标准输入、输出和错误流默认就会关联到控制终端对应的设备文件上。**云服务器上文件描述符012指向的文件:

      image-20250207173240326

    • 虚拟机中(也类似):

      image-20250207174036657

  3. 作业控制:允许用户管理属于当前shell会话的不同任务(作业)。这包括将作业放到后台执行或从前台恢复执行。作业和前台后台进程的概念我们稍后会谈。

会话、终端、bash三者的关系

Linux中的shell进程叫做bash,当用户通过xshell等ssh远程登录客户端中的终端登录后,这个终端成为bash进程的控制终端,而这个终端中的所有进程组(前台和后台)构成一个会话(当你登录系统并启动bash时,实际上就开启了一个新的会话。),画图来表示就是下面这样:

image-20250207181459757

前台进程与后台进程

概念

前台进程和后台进程都是进程,唯一区别就是前台进程可以通过终端接收用户的输入,同时也可以接收来自用户的命令(ctrl Cctrl Z),前台进程还可以将输出输入到显示器(也就是终端上)。但是后台进程则不同,它不直接与用户交互,即它们不接受键盘输入,也不将输出直接显示给用户(除非特别配置)。

特点

  1. 前台进程
    • 独占性:同一终端,同一时刻,只能有一个进程或进程组。这意味着前台进程对输入输出有独占性。
    • 用户交互:前台进程可以直接通过终端与用户进行交互。这意味着它可以接受用户的输入,并将其显示在屏幕上。通常用户输入的命令,就是在前台运行。
    • 信号响应:前台进程组可以接收到某些类型的信号,比如通过按下Ctrl+C发送的SIGINT中断信号来终止当前操作。这是前台进程的一个重要特性,允许用户直接控制正在运行的程序。
  2. 后台进程
    • 并发执行:多个后台进程可以同时执行(并发是看似同时执行,实则轮询执行),一个终端可以有多个后台作业同时执行。
    • 无需与用户交互:不接收用户的输入,也不会将输出直接显示给用户。
    • 信号限制ctrl C等命令无法作用于后台进程,要使用killkillall等命令。

查看当前终端的后台进程

命令jobs可以查看当前终端的后台进程,它会显示每个后台作业的作业号和状态。

jobs

选项-l:添加 -l 选项后,jobs 命令不仅显示基本的作业信息,还会额外列出每个作业的进程ID(PID)。

前台进程与后台进程的切换

  1. 前台进程切换为后台进程

    • 方法1:在执行一个程序时,在后面加上&

      image-20250207183742115

    • 方法2ctrl Z暂停某个正在执行的前台进程,它将被切为后台进程:

      image-20250207184541663

    • 方法3:当某个子进程的父进程结束,它还在运行时它就会变成孤儿进程。无法通过ctrl C命令终止它的运行,因为孤儿进程被initSIDPID为1)进程收养,但可以通过killkillall命令终止它。可以认为这是一种特殊情况。

  2. 后台进程切换为前台进程

    • 使用命令fg(foreground的缩写)将后台进程切换为前台进程:

      fg 作业号
      

      image-20250207193051184

    • 扩展命令bg,这个命令可以将暂停的命令继续在后台运行。

      bg
      

    `
    image-20250207193909521

作业控制

相关概念

作业

作业是指Linux系统中正在运行的一个进程或者进程组(多个进程)。进程之间一般通过管道来互相协作。

作业控制

shell可以同时运行一个前台作业和多个后台作业,这叫做作业控制。前台作业和后台作业都可以由多个进程组成。

作业号

作业号是后台作业专有的,它们在开始执行时或者执行完后会返回一个作业号。

示例1

echo "1111" &

image-20250208174913663

示例2

sleep 1000 | sleep 2000 | sleep 3000 &

image-20250208175050370

  • [1]就是该作业的作业号。

作业状态(一般指后台作业)

常见的作业有以下状态:

作业状态含义
正在运行(Running)后台作业(&),正在运行
暂停运行(Stopped)前台作业被ctrl z(或者是后台作业被相应的信号所暂停)暂停了
完成(Done)后台作业已完成执行(返回的状态码为0)
完成(Done(code))后台作业完成执行(返回的状态码非0)
终止(Terminated)后台作业被终止
  1. Running状态:

    image-20250208180841505

  2. Stopped状态:

    image-20250208181403878

  3. Done状态:

    image-20250208181451788

  4. Terminated状态:

    image-20250208181651879

  5. Done(code)状态。后台执行下面的脚本文件:

    exit 42 # 返回退出状态码42
    

    image-20250208182301269

守护进程

概念

守护进程不同于普通的后台进程(作业),普通的后台作业它有关联的终端,即使不与用户交互或者不输出内容到用户的显示器上,但是守护进程有自己独立的会话,并且它无终端关联,脱离终端控制,除非系统关闭,否则守护进程不会轻易的关闭。

常见的守护进程:比如httpd(Apache HTTP服务器)、sshd(SSH服务器)、crond(定时任务调度器)等都是典型的守护进程,它们为系统提供核心服务。

普通后台程序:例如,你在终端中运行的一个长时间的数据处理脚本,并在其后加上&让它在后台运行。这个脚本就是一个普通的后台程序,而不是守护进程。

将进程守护化

进程守护化的步骤

  1. 父进程fork子进程:让父进程退出,后续都是子进程来执行相关程序,并成为守护进程,因为创建一个新的会话需要该进程不是进程组的组长。这是系统设计所决定的,如果不这样做,会有循环依赖问题。
  2. setsid() 创建新会话:使子进程成为新会话的领导者,并脱离所有终端的控制,确保它没有控制终端。
  3. 改变当前工作目录(如果需要):通常是切换到根目录(/),以避免占用挂载点。
  4. 重定向标准输入、输出和错误流(如果后面不使用也可以关闭):通常指向/dev/null或其他适当的日志文件,以防止无意中使用这些默认流。/dev/null文件读取都会读到null,写入都会被自动丢弃。
  5. 关闭不需要的文件描述符:确保除了必要的资源外,其他文件描述符都被关闭。

代码实现

#include<stdio.h>
#include<unistd.h>
#include<stdbool.h>
#include <fcntl.h>
#include <stdlib.h>
#include <signal.h>const char* newdir = "/";
const char* newpath = "/dev/null";
void Demon(bool IsChangeWorkDir,bool IsRedir)
{//0.忽略可能引起程序异常的信号// 忽略SIGCHLD信号,防止产生僵尸进程signal(SIGCHLD, SIG_IGN);// 忽略SIGPIPE信号,避免程序因写入已关闭的pipe/socket而终止signal(SIGPIPE, SIG_IGN);//1.创建子进程,并让父进程退出if(fork() > 0){printf("pid is %d\n",getpid());exit(0);}//2.让子进程新建一个会话,成为守护进程,子进程成为新会话的leader进程,会话ID和这个子进程的进程ID相同setsid();//3. 已经成为守护进程,查看是否需要更改工作目录if(IsChangeWorkDir){chdir(newdir);}//4.查看是否需要重定向0、1、2标准输入、输入、错误流if(IsRedir){int fd = open(newpath,O_RDWR);//以读写模式打开dup2(fd,0);dup2(fd,1);dup2(fd,2);close(fd);//不需要fd了}else{close(0);close(1);close(2);}
}
int main()
{Demon(true,true);while(true);//变成守护进程了return 0;
}

运行结果:

image-20250208193403430

相关文章:

【Linux网络编程】之守护进程

【Linux网络编程】之守护进程 进程组进程组的概念组长进程 会话会话的概念会话ID 控制终端控制终端的概念控制终端的作用会话、终端、bash三者的关系 前台进程与后台进程概念特点查看当前终端的后台进程前台进程与后台进程的切换 作业控制相关概念作业状态&#xff08;一般指后…...

MarkupLM:用于视觉丰富文档理解的文本和标记语言预训练

摘要 结合文本、布局和图像的多模态预训练在视觉丰富文档理解&#xff08;VRDU&#xff09;领域取得了显著进展&#xff0c;尤其是对于固定布局文档&#xff08;如扫描文档图像&#xff09;。然而&#xff0c;仍然有大量的数字文档&#xff0c;其布局信息不是固定的&#xff0…...

了解AI绘图,Stable Diffusion的使用

AI绘图对GPU算力要求较高。 个人电脑配置可参考&#xff1a; CPU&#xff1a;14600kf 盒装 显卡&#xff1a;RTX 4080金属大师 OC&#xff0c;16G显存 主板&#xff1a;z790吹雪d4 内存&#xff1a;芝奇皇家戟4000c18,162G 硬盘&#xff1a;宏基gm7000 1T 散热&#xff1a;追风…...

jakarta EE学习笔记-个人笔记

WebServlet注解&#xff1a;声明一个类为Servlet Target({ElementType.TYPE}) Retention(RetentionPolicy.RUNTIME) Documented public interface WebServlet {// 指定Servlet的影子String name() default ""; // 匹配地址映射(URL)String[] value() default {};// …...

Kokoro 开源文本转语音引擎上线!多语言支持,无需联网,浏览器内极速运行

Kokoro 是一款轻量级的开源文本转语音(TTS)引擎,凭借其高效能和轻量化设计,迅速在技术社区中引起关注。本文将详细介绍 Kokoro 的主要特点,并提供在浏览器和 Python 环境中的代码示例,帮助您快速上手。 1. Kokoro:可在浏览器中运行的 TTS 引擎 1.1 简介 Kokoro 是一个…...

VSCode使用总结

1、VSCode左边资源窗口字体大小设置 方法一&#xff08;使用&#xff0c;已成功&#xff09; 进入安装目录Microsoft VS Code\resources\app\out\vs\workbench(如果是下载的压缩包&#xff0c;解压后resources\app\out\vs\workbench) 打开文件 workbench.desktop.main.css 搜…...

淘宝分类详情数据获取:Python爬虫的高效实现

在电商领域&#xff0c;淘宝作为中国最大的电商平台之一&#xff0c;其分类详情数据对于市场分析、竞争对手研究以及电商运营优化具有不可估量的价值。通过Python爬虫技术&#xff0c;我们可以高效地获取这些数据&#xff0c;为电商从业者提供强大的数据支持。 一、为什么选择…...

DeepSeek LLM 论文解读:相信长期主义开源理念可扩展大语言模型(DeepSeek 吹响通用人工智能的号角)

论文链接&#xff1a;DeepSeek LLM: Scaling Open-Source Language Models with Longtermism&#xff08;相信长期主义开源理念可扩展大语言模型&#xff09; 目录 摘要一、数据处理&#xff08;一&#xff09;数据清洗与丰富&#xff08;二&#xff09;分词器与词汇设置 二、模…...

嵌入式AI革命:DeepSeek开源如何终结GPU霸权,开启单片机智能新时代?

2025年&#xff0c;全球AI领域最震撼的突破并非来自算力堆叠的超级模型&#xff0c;而是中国团队DeepSeek通过开源策略&#xff0c;推动大模型向微型化、低功耗场景的跨越。相对于当人们还在讨论千亿参数模型的训练成本被压缩到600万美金而言&#xff0c;被称作“核弹级别”的操…...

【EPSG 坐标系系统完全解析(二)(万字详述)】

地理坐标系系统完全解析&#xff08;万字详述&#xff09; 第一章 坐标系基础理论&#xff08;2000字&#xff09; 1.1 地球空间参照系 1.1.1 地球椭球体模型 参考椭球参数对比&#xff1a; 椭球体长半轴&#xff08;m&#xff09;短半轴&#xff08;m&#xff09;使用国家/…...

fastchat 部署大模型

大模型实战--Llama3.1大模型部署及启动Web UI、OpenAI API实操 - 简书一、背景 随着人工智能技术的飞速发展&#xff0c;大模型&#xff08;Large Language Models, LLMs&#xff09;已成为自然语言处理领域的核心工具。这些模型以其强大的语言理解和生成能力&#xff0c;...ht…...

【安当产品应用案例100集】037-强化OpenVPN安全防线的卓越之选——安当ASP身份认证系统

在当前数字化时代&#xff0c;网络安全已成为企业发展的重要组成部分。对于使用OpenVPN的企业而言&#xff0c;确保远程访问的安全性尤为重要。安当ASP身份认证系统凭借其强大的功能和便捷的集成方式&#xff0c;为OpenVPN的二次登录认证提供了理想的解决方案&#xff0c;特别是…...

协议-ACLLite-ffmpeg

是什么&#xff1f; FFmpeg是一个开源的多媒体处理工具包&#xff0c;它集成了多种功能&#xff0c;包括音视频的录制、转换和流式传输处理。FFmpeg由一系列的库和工具组成&#xff0c;其中最核心的是libavcodec和libavformat库。 libavcodec是一个领先的音频/视频编解码器库&…...

树和二叉树_7

树和二叉树_7 一、leetcode-102二、题解1.引库2.代码 一、leetcode-102 二叉树的层序遍历 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 样例输入&#xff1a;root [3,9,20,null,nu…...

【C#】一维、二维、三维数组的使用

在C#中&#xff0c;数组是用于存储固定数量相同类型元素的数据结构。根据维度的不同&#xff0c;可以分为一维数组、二维数组&#xff08;矩阵阵列&#xff09;、三维数组等。每增加一个维度&#xff0c;数据的组织方式就会变得更加复杂。 一维数组 一维数组是最简单的数组形…...

Dubbo 3.x源码(30)—Dubbo Consumer服务调用源码(2)发起远程调用

基于Dubbo 3.1&#xff0c;详细介绍了Dubbo Consumer服务调用源码。 上文我们学习了&#xff0c;Dubbo 发起服务调用的上半部分源码&#xff0c;我们学习到了FailoverClusterInvoker最终会通过服务提供者Invoker#invoke发起RPC调用&#xff0c;下面我们来学习Dubbo 发起服务调用…...

学习日记-250207

一.论文 1.Prompt Learning for News Recommendation 任务不一致&#xff08;LLM与实际任务&#xff09;产生prompt提示。 Prompt Learning for News Recommendation 论文阅读 SIGIR2023-CSDN博客 2.GPT4Rec: A Generative Framework for Personalized Recommendation and…...

Rocky Linux9安装Zabbix7.0(精简版)

Linux 系统版本 Rocky Linux release 9.3 (Blue Onyx) 注意&#xff1a;zabbix 7以上版本不支持CentOS 7系统&#xff0c;需要CentOS 8以上&#xff0c; 本教程支持CentOS9及Rocky Linux 9 在Rocky Linux release 9.3测试通过 Linux环境准备 关闭防火墙和selinux #关闭防…...

网络分析工具—WireShark的安装及使用

Wireshark 是一个广泛使用的网络协议分析工具&#xff0c;常被网络管理员、开发人员和安全专家用来捕获和分析网络数据包。它支持多种网络协议&#xff0c;能够帮助用户深入理解网络流量、诊断网络问题以及进行安全分析。 Wireshark 的主要功能 数据包捕获与分析&#xff1a; …...

C++开发(软件开发)常见面试题

目录 1、C里指针和数组的区别 2、C中空指针请使用nullptr不要使用NULL 3、http/https区别和头部结构&#xff1f; 4、有了mac地址为什么还要ip地址&#xff1f;ip地址的作用 5、有了路由器为什么还要交换机&#xff1f; 6、面向对象三大特性 7、友元函数 8、大端小端 …...

云原生后端|实践?

云原生&#xff08;Cloud Native&#xff09;是一种构建和运行应用程序的方法&#xff0c;它充分利用云计算的优势&#xff0c;包括弹性、可扩展性、高可用性和自动化运维。云原生后端开发通常涉及微服务架构、容器化、持续集成/持续部署&#xff08;CI/CD&#xff09;、服务网…...

WEB攻防-文件下载文件读取文件删除目录遍历目录穿越

目录 一、文件下载漏洞 1.1 文件下载案例&#xff08;黑盒角度&#xff09; 1.2 文件读取案例&#xff08;黑盒角度&#xff09; 二、文件删除 三、目录遍历与目录穿越 四、审计分析-文件下载漏洞-XHCMS 五、审计分析-文件读取漏洞-MetInfo-函数搜索 六、审计分析-…...

to_csv保存指定列的方法

df是DataFrame的数据&#xff0c;它的列为[代码, 名称, 最高, 最低] 现在我只想将‘代码’、“名称”两列内容存入csv&#xff0c;实现如下&#xff1a; columns_to_save [代码, 名称] df.代码 df.代码.apply("{}".format)#此行可以防止代码之前的0被忽略掉 d…...

MySQL数据库(七)SQL 优化

一 插入数据 采用方法 1 批量插入 2 手动提交事务 3 主键顺序插入 4* 使用load插入指令数据 二 主键优化 1 数据组织方式 在InnoDB存储引擎中&#xff0c;表中的数据都是根据主键顺序组织存放的&#xff0c;这种存储方式的表称为索引组织表 2 页分裂 页可以为空也可…...

使用EVE-NG实现单臂路由

一、基础知识 1.三层vlan vlan在三层环境中通常用作网关vlan配上ip网关内部接口ip 2.vlan创建步骤 创建vlan将接口划分到不同的vlan给vlan配置ip地址 二、项目案例 1、项目拓扑 2、项目实现 PC1配置 配置PC1IP地址为192.168.1.10/24网关地址为192.168.1.1 ip 192.168.1…...

flask开发的网站,后端服务关闭后,可以找回之前的数据的吗

如果使用 Flask 开发的网页&#xff0c;后端服务关闭后&#xff0c;是否还能找回数据取决于数据的存储方式&#xff1a; 可能找回数据的情况&#xff1a; 数据库存储&#xff08;MySQL、PostgreSQL、SQLite 等&#xff09; 如果 Flask 连接的是持久化数据库&#xff0c;即使后…...

疯狂SQL转换系列- SQL for Milvs2.4

鉴于Milvus仍在不停的迭代新版本&#xff0c;推出新功能&#xff0c;其SDK目前并不稳定。目前其2.4版本的SDK接口已与之前的2.2版本有了较大的差别&#xff0c;功能上也有了一定的调整。为此&#xff0c;我们重新提供了针对[Milvus2.4](https://github.com/colorknight/moql-tr…...

本地部署DeepSeek(Mac版本,带图形化操作界面)

一、下载安装&#xff1a;Ollama 官网下载&#xff1a;Download Ollama on macOS 二、安装Ollama 1、直接解压zip压缩包&#xff0c;解压出来就是应用程序 2、直接将Ollama拖到应用程序中即可 3、启动终端命令验证 # 输入 ollama 代表已经安装成功。 4、下载模型 点击模型…...

Linux LED 实验

一、Linux 下 LED 灯驱动原理 其实跟裸机实验很相似&#xff0c;只不过要编写符合 Linux 的驱动框架。 1. 地址映射 MMU全称 Memory Manage Unit&#xff0c;即内存存储单元。 MMU主要功能为&#xff1a; 1&#xff09;完成虚拟空间到物理空间的映射&#xff1b; 2&#x…...

深入解析:Jsoup 库的多功能应用场景

Jsoup 是一个强大的 Java 库&#xff0c;主要用于解析和操作 HTML 文档。它不仅广泛应用于网络爬虫和数据抓取&#xff0c;还在网页内容分析、数据清洗与处理、自动化测试等多个领域有着广泛的应用。本文将详细介绍 Jsoup 库的多种用途&#xff0c;并提供具体的代码示例。 一、…...