【Linux】守护进程

news2024/11/15 12:29:50

文章目录

  • 任务管理
    • 进程组
    • 作业
    • 会话
    • 任务管理操作
      • 相关操作
  • 守护进程
    • 创建守护进程
    • daemon函数创建守护进程
    • 所谓的项目部署

任务管理

进程组

进程组是一个或多个进程的集合。每个进程除了有一个进程ID之外,还属于一个进程组。

每个进程组有一个唯一的进程组ID。每个进程组都有一个组长进程。组长进程ID等于其进程组ID。

作业

SHELL终端通过前后台来控制作业和进程组。

一个前台作业可以由多个进程组成,一个后台作业也可以由多个进程组成,Shell可以运行一个前台作业和任意多个后台作业,这称为作业控制。

会话

会话是一个或者多个进程组的集合

  • 一个会话可以有一个控制终端。建立与控制终端连接的会话首进程被称为控制进程。

  • 一个会话中的几个进程组可被分为一个前台进程组以及一个或多个后台进程组。

  • 一个会话包括:一个控制进程,一个前台进程和多个后台进程。

创建四个死循环程序

image-20221203235748418

下面将job1和job2放在一个进程组,job3和job4放在一个进程组

image-20221204000416339

  • TTY:与进程关联的终端(tty)(完整的终端名称)
  • SID:会话组ID

这些进程组的控制终端相同,它们同属于一个会话。

任务管理操作

直接运行某一可执行程序,例如./可执行程序,此时默认将程序放到前台运行,在前台运行的进程的状态后有一个+号,例如s+

image-20221204001421344

运行可执行程序时在后面加上&,可以指定将程序放到后台运行,例如./可执行程序 &

image-20221204001551468

[1] 7358
[2] 7460

每创建一个后台进程组(作业),就会提升一条[ num ] NUM的信息;这里[ num ]是作业的编号。NUM是该作业中某个进程的进程ID。

相关操作

job命令

job命令,可以查看当前会话有那些工作

image-20221204004045827

fg命令

使用fg命令(foreground),可以将某个作业提至前台运行,如果该作业正在后台运行则直接提至前台运行,如果该作业处于停止状态,则给进程组的每个进程发SIGCONT信号使它继续运行并提至前台。

image-20221204004322628

job1和job2的状态从S变为了S+。

需要注意的是:前台进程只能有一个,当一个进程变成前台进程后,bash会自动变为后台进程,此时bash就无法进行命令行解释了。

image-20221204004652440

bash相关进程的+都没有了。

bg命令

使用bg命令,可以让某个停止的作业在后台继续运行(Running),本质就是给该作业的进程组的每个进程发SIGCONT信号。

image-20221204005329747

守护进程

守护进程也称精灵进程(Daemon),是运行在后台的一种特殊进程,它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。

Linux系统启动时会启动很多系统服务进程,这些系统服务进程没有控制终端,不能直接和用户交互。

其他进程都是在用户登录或运行程序时创建,在运行结束或用户注销时终止,但系统服务进程不受用户登录注销的影响,它们一直在运行着,这种进程有一个名称叫守护进程。

Linux系统中存在大量的守护进程,下面使用ps ajx命令查看。

image-20221204005744803

  • TPGID为终端的前台进程组。TPGID为-1的就是守护进程

创建守护进程

守护进程的创建步骤如下:

  1. 设置文件掩码为0。
  2. 忽略SIGCHLD信号。
  3. fork,终止父进程,保持子进程不是会话首进程,从而保证后续不会再和其他终端相关联。
  4. 将子进程设置为一个独立的会话
  5. 将标准输入、标准输出、标准错误重定向到/dev/null。

为什么需要将子进程设置为一个单独的会话,而不是父进程?

一般在一个多进程工作中,父进程即为进程组的组长。而组长管理整个进程组。

一个守护进程的父进程是init进程,需要单独设为一个会话,不与终端交互;一旦一个进程组的组长被设置为一个守护进程,那么原进程组就没有进程组组长。

#include <cstdio>
#include <iostream>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
void daemonize()
{
    umask(0);
    int fd = 0;
    // 1. 忽略SIGPIPE
    signal(SIGPIPE, SIG_IGN);
    signal(SIGCHLD,SIG_IGN);	
    // 2. 更改进程的工作目录
    // chdir();
    // 3. 让自己不要成为进程组组长
    if (fork() > 0){
        exit(1);
    }
    
    // 4. 设置自己是一个独立的会话
    setsid();
    // 5. 重定向0,1,2
    if ((fd = open("/dev/null", O_RDWR)) != -1) // fd == 3
    {
        dup2(fd, STDIN_FILENO);
        dup2(fd, STDOUT_FILENO);
        dup2(fd, STDERR_FILENO);
        // 6. 关闭掉不需要的fd
        if(fd > STDERR_FILENO) close(fd);
    }
}

关于/dev/null

/dev/null可以理解为Linux下的垃圾回收箱。我们可以通过把命令的输出重定向到 /dev/null 来丢弃脚本的全部输出。

守护进程不能直接和用户交互,所以可以把守护进程的输出都重定到/dev/null文件中。

daemon函数创建守护进程

int daemon(int nochdir, int noclose);

参数说明:

  • 如果参数nochdir为0,则将守护进程的工作目录该为根目录,否则不做处理。
  • 如果参数noclose为0,则将守护进程的标准输入、标准输出以及标准错误重定向到/dev/null,否则不做处理。

所谓的项目部署

项目部署中很重要的一步就是将服务后台化,这里的后台化就是将进程**变成守护进程,**我们以一个TCP服务端为例

源码地址:

socket · 影中人/test - 码云 - 开源中国 (gitee.com)

int main(int argc, char *argv[])
{
    if (argc != 2 && argc != 3)
    {
        Usage(argv[0]);
        exit(3);
    }
    uint16_t port = atoi(argv[1]);
    std::string ip;
    if (argc == 3)
    {
        ip = argv[2];
    }
    //将进程守护进程化
    daemonize();
    //创建TCP服务器并运行
    Tcpserver svr(port, ip);
    svr.init();
    svr.start();
    return 0;
}

image-20221204013602018

使用daemon守护进程化

int main(int argc, char *argv[])
{
    if (argc != 2 && argc != 3)
    {
        Usage(argv[0]);
        exit(3);
    }
    uint16_t port = atoi(argv[1]);
    std::string ip;
    if (argc == 3)
    {
        ip = argv[2];
    }
    //守护进程化
    daemon(0,0);
    //创建服务器和运行
    Tcpserver svr(port, ip);
    svr.init();
    svr.start();
    return 0;
}

image-20221204014153066

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/59689.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CTFShow re2 (RC4

参考&#xff1a;CTFSHOW re2 本文&#xff1a;跟着大佬的博客一步一步做CTFShow re2的记录 IDA分析 有个比较函数 re一下 s "DH~mqqvqxB^||zllJq~jkwpmvez{" s1 for i in s:s1 chr(ord(i) ^ 0x1f) print(s1)得到 再四处看看 跟进sub_401028 四个sub点进去看看…

禅道登录-调用API方式

禅道提供了API机制方便于大家和其他的系统进行集成&#xff0c;API机制也都是基于http协议的&#xff0c;返回的数据以json格式存储。禅道的API都是需要先登录后才能进行接口调用&#xff08;登录返回的cookie需要在之后的每次请求中携带用于验证身份信息&#xff09;。网上关于…

DNS中有哪些值得学习的优秀设计

为什么要有DNS 如果我们想要访问某度&#xff0c;你可以在浏览器上的搜索栏里输入112.80.248.76这个IP地址&#xff0c;直达页面。 通过IP访问网页 这样的行为&#xff0c;合法&#xff0c;但有病。 大部分人&#xff0c;连自己对象的电话号码都记不住&#xff0c;又怎么可能…

shell脚本受限执行

shell 中运行的脚本或脚本的个代码断会禁用一些正常 shell 中可以执行的命令.这是限制脚本用户的权限和最小化运行脚本导致的破坏的安全措施.受限的内容包括&#xff1a;使用 cd 命令更改工作目录. 更改环境变量$PATH, $SHELL, $BASH_ENV,或$ENV 的值. 读或更改 shell 环境选项…

ARM 反汇编工具objdump的使用简介

一、反汇编的原理 & 为什么要反汇编 arm-linux-objdump -D led.elf > led_elf.dis-D, --disassemble-all Display assembler contents of all sectionsobjdump 是 gcc 工具链中的反汇编工具&#xff0c;作用是由编译链接好的 elf 格式的可执行程序反过来得到汇编源代…

【期末大作业】基于HTML+CSS+JavaScript网上订餐系统(23个页面)

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

26-38-javajvm-类加载器子系统

26-javajvm-类加载器子系统&#xff1a; 1.内存结构概述 2.类加载子系统 2.1 类加载器子系统的作用 1&#xff09;、类加载器子系统负责从文件系统或者网络中加载Class文件&#xff0c;class文件在文件开头有特定的文件标识。 2&#xff09;、ClassLoader只负责class文件的加…

常用的shell命令

常用的shell命令 1、ls命令 功能&#xff1a;显示文件和目录的信息 ls 以默认方式显示当前目录文件列表 ls -a 显示所有文件包括隐藏文件 ls -l 显示文件属性&#xff0c;包括大小&#xff0c;日期&#xff0c;符号连接&#xff0c;是否可读写及是否可执行 ls -lh 显示文件的…

1547_AURIX_TC275_CPU子系统_数据存储接口

全部学习汇总&#xff1a; GreyZhang/g_TC275: happy hacking for TC275! (github.com) 这个可以对比PMI来看一下&#xff0c;相比于PMI&#xff0c;DMI的结构简单很多。 1. 之前在看cache以及其对指令读取速度影响的时候&#xff0c;可能弄错了一个概念。如果cache不命中&…

【JavaEE】认识多线程(一)

✨哈喽&#xff0c;进来的小伙伴们&#xff0c;你们好耶&#xff01;✨ &#x1f6f0;️&#x1f6f0;️系列专栏:【JavaEE】 ✈️✈️本篇内容:了解多线程(初阶) &#x1f680;&#x1f680;代码存放仓库gitee&#xff1a;JavaEE初阶代码存放&#xff01; ⛵⛵作者简介&#x…

单变量微积分重点(2)

泰勒公式 用柯西定理证明 拉格朗日余项 麦克劳林展开式&#xff1a; 皮亚诺余项的泰勒公式&#xff1a; 弧长的微分 注意s(t)需要在后面证明&#xff08;定积分的知识&#xff09; 不定积分&#xff1a; 注意&#xff0c;不同的积分方法经常会得到不同的结果&#xff0c;但它们…

IDEA如何配置 Gradle 及 Gradle 安装过程(详细版)

IDEA如何配置 Gradle&#xff08;详细版&#xff09; 一、安装 Gradle 1、下载 Gradle 安装包 官网下载链接&#xff1a;https://gradle.org/releases/ 2、下载后解压 3、文件夹如图所示 二、环境变量配置 1、点击我的电脑->属性->高级系统设置->环境变量 2、新建&…

[附源码]JAVA毕业设计抗击新冠疫情专题宣传网站(系统+LW)

[附源码]JAVA毕业设计抗击新冠疫情专题宣传网站&#xff08;系统LW&#xff09; 目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 …

JSP+MySQL绿色环境保护网站的设计于实现

环保已经是当前中国的一个基本国策,国家领导人和各地政府也制定了一系列相关的政策来号召全民积极的参加到环保事业中来,为了能够更好的响应多家的号召我们开发了本JSP&#xff1a;MySQL&#xff1a;SSH 绿色环保网站,希望更多的人能够积极的参加到环保事业中来,本网站通过环境…

华为模拟器手把手安装教程-HCIE(华为网络工程师)

一、准备工作 请各位提前准备好eNSP_Setup安装程序、VirtualBox安装程序、Wireshark-win64位安装程序和WinPcap安装程序&#xff08;在wireshark安装过程中可以一起安装&#xff0c;也可以单独安装&#xff09;&#xff0c;获取相关安装程序文件可以联系小编哦&#xff01; 二、…

【蓝桥杯】第十四届模拟赛第一期及第二期填空汇总

目录 1.A题&#xff08;进制位数&#xff09; 位运算符 第一期 问题描述 解析 第二期 解析 代码 2.B题&#xff08;日期问题&#xff09; 第一期 问题描述 解析 代码实现 执行结果 第二期 问题描述 解析 3.C题&#xff08;数学问题&#xff09; 第一期 问题…

windows域控上批量修改域账号密码

目录 一、查询密码过期域账号信息 &#xff08;一&#xff09;根据OU组织架构查询密码过期账号 &#xff08;二&#xff09;查询域控所有密码过期账号 &#xff08;三&#xff09;导出dsquery查询的信息 二、批量修改过期域账号密码 &#xff08;一&#xff09;根据dsque…

【YOLO系列改进NO.47】改进激活函数为GELU

文章目录前言一、解决问题二、基本原理三、​添加方法四、总结前言 作为当前先进的深度学习目标检测算法YOLOv7&#xff0c;已经集合了大量的trick&#xff0c;但是还是有提高和改进的空间&#xff0c;针对具体应用场景下的检测难点&#xff0c;可以不同的改进方法。此后的系列…

Go-Excelize API源码阅读(四十)——SetCellRichText

Go-Excelize API源码阅读&#xff08;四十&#xff09;——SetCellRichText 开源摘星计划&#xff08;WeOpen Star&#xff09; 是由腾源会 2022 年推出的全新项目&#xff0c;旨在为开源人提供成长激励&#xff0c;为开源项目提供成长支持&#xff0c;助力开发者更好地了解开…

Android 虚拟分区详解(二) 虚拟分区布局

文章目录0. 导读1. Android 传统 A/B 分区和动态分区布局2. Android 虚拟分区布局3. 虚拟分区的思考2.1 分区只有一套&#xff0c;如何实现 A/B 系统特性&#xff1f;2.2 部分分区还有 A/B 两套&#xff0c;只要一套不行吗&#xff1f;2.3 为什么不把所有分区都放到动态分区里&…