Linux任务管理与守护进程

目录

任务管理

jobs,fg,bg

进程组概念

任务概念

守护进程

守护进程的概念

守护进程的查看

守护进程的创建

​编辑模拟实现daemon函数


任务管理

每当有一个用户登录Linux时,系统就会创建一个会话(session)

任何进程都可以被设置为前台进程,只要前台进程被干掉系统会自动的将bash放到前台变成前台进程

我下面写了一个死循环,创建一个文件 test.cc 测试它被干掉之后bash进程是否会自动顶替它

可以看到在a.out运行期间不管我们输入多少次指令都是没有响应的,原因就是此时的前台进程已经不是bash了,当我们使用ctrl + c将a.out终止之后就可以看到,我们输入的ls指令受到了响应,原因就是a.out执行结束之后,前台进程被bash自动顶上了

jobs,fg,bg

将当前任务变成前台任务

当我们以后台进程的方式运行a.out时,我们发送的指令,bash是会给我们进行响应的,那我们如果想将a.out变成前台进程应该怎么做呢?

fg + 任务号

任务号:

为了方便演示我们将a.out打印的值追加重定向到log.txt中

同样的,我们创建三个文件 test.cc,test1.cc,test2.cc 让它生成可执行程序

然后将这三个启动的进程追加重定向到log.txt中

我们可以使用 jobs 指令来查看当前会话中的所有后台进程

后台进程的杀死方式

1.可以使用kill直接杀掉进程

2.提到前程,再使用键盘组合键杀死

暂停前台进程 ctrl + z 组合键

当我们使用ctrl + z将前台进程暂停之后,系统会将bash提到前台,让bash充当前台进程

此时我们向键盘文件中输入 ls pwd 指令是没有响应的

当我们使用ctrl+z将该进程暂停之后,bash自动充当前台进程,这时我们输入指令就会得到响应

恢复已经暂停的进程   bg指令

使用方式:bg + 任务号

怎么区分前台进程和后台进程?

后台进程无法从标准输入获取数据,所以谁拥有键盘文件,谁就是前台进程

进程组概念

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

通常它们与同任务相关联,可以接收来自同一终端的各种信号。每个进程组有一个唯一的进程组ID。每个进程组都有一个组长进程。组长进程的标识是,其进程组ID等于其进程ID。组长进程可以创建一个进程组,创建该组中的进程,然后终止

注意:进程组中,只要有进程存在则该进程组就存在,这与其组长进程是否终止无关

PGID:进程组ID

SID:用来标识系统中的某一个会话(session)

TTY:该用户使用的终端编号

注意:前台进程的状态后面有一个 + 号,后台进程则没有 + 号 

任务概念

Shell分前后台来控制的不是进程而是任务或者进程组

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

作业和进程组的区别:

如果作业中的某个进程有创建出了子进程,则子进程不属于任务,一旦任务运行结束,Shell就把自己提到前台,如果原来前台进程还存在,也就是这个被创建的子进程还没有终止,那么它将自动变为后台进程组

守护进程

守护进程的概念

此时,我们打开三个后台进程,我们看看用户退出时这三个进程是否会收到影响

用户退出之后,启动的进程也随之受到了影响

怎么让这些进程不受到用户登录和退出的影响呢?我们可以将这些进程守护进程化

怎么让进程守护进程化

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

守护进程是一种很有用的进程,Linux的大多数服务器就是用守护进程实现的,比如Internet服务器inetd,Web服务器httpd等。同时守护进程完成许多系统任务,比如作业规划进程crond等。

Linux系统启动时会启动很多系统服务进程,这些系统服务进程没有控制终端,不能直接和用户交互。其他进程都是在用户登录或运行程序时创建,在运行结束或用户注销时终止,但系统服务进程不受用户登录注销的影响,它们一直在运行着,这种进程有一个名称叫守护进程(Daemon)。

守护进程的查看

我们可以使用ps ajx指令查看系统中的进程:

  • 参数a表示不仅列出当前用户的进程,也列出所有其他用户的进程。
  • 参数x表示不仅列出有控制终端的进程,也列出所有无控制终端的进程。
  • 参数j表示列出与作业控制相关的信息。

凡是TPGID一栏写着-1的都是没有控制终端的进行,也就是守护进程

除此之外,在COMMAND一列用[ ]括起来的名字表示内核线程,这些线程在内核里创建,没有用户空间代码,因此没有程序文件名和命令行,通常采用以k开头的名字,表示Kernel。

个别说明:

  • udevd负责维护/dev目录下的设备文件。
  • acpid负责电源管理。
  • syslogd负责维护/var/log下的日志文件。

可以看出,守护进程通常采用以d结尾的名字,表示Daemon。

守护进程的创建

1.忽略其他异常信号,以免收到信号影响到守护进程(SIGCLD,SIGPIPE,SIGSTOP)

2.将自己变成独立的会话

3.更改当前调用进程的工作目录

4.将标准输入,标准输出,标准错误重定向到 dev/null 中

相关说明:

1.调用setsid创建新会话的目的,是让当前进程自称会话与当前的bash脱离关系(创建守护进程的核心)。

2.调用setsid创建新会话时,要求调用进程不能是进程组组长,但是当我们在命令行上启动多个进程协同完成某种任务时,其中第一个被创建出来的进程就是组长进程,因此我们需要fork创建子进程,让子进程调用setsid创建新会话并继续执行后续代码,而父进程直接退出即可

3.我们一般将守护进程的工作目录设置为根目录,便于让守护进程以绝对路径的方式访问某种资源

4.守护进程不能直接和用户交互,也就是说守护进程已经与终端去关联了,因此一般我们会将守护进程的标准输入,标准输出,标准错误都重定向到 /dev/null 中, /dev/null是一个字符文件(设备),通常用于屏蔽、丢弃输入输出信息

#include <iostream>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string>const std::string filename = "/dev/null";//守护进程化
int main()
{// 1.屏蔽信号signal(SIGCLD, SIG_IGN);signal(SIGPIPE, SIG_IGN);signal(SIGSTOP, SIG_IGN);// 2.fork子进程,子进程执行setsid(),创建守护进程,父进程退出if (fork() > 0)exit(0);setsid();// 3.将守护进程的工作路径更改为根目录chdir("/");// 由于守护进程没有终端,不能和用户进程交互,所以我们需要将标准输入,标准输出,标准错误重定向到 /dev/null下int fd = open(filename.c_str(), O_RDWR, 000);dup2(fd, 0);dup2(fd, 1);dup2(fd, 2);return 0;
}

可以看到当前进程已经和终端去关联了

通过 ls /proc/进程id -al 命令我们可以看到该进程的工作目录已经成功修改为了根目录

通过 ls /proc/进程id/fd -al 命令,我们可以看到该进程的标准输入,标准输出,标准错误,重定向到了 /dev/null

调用daemom创建守护进程

实际当我们创建守护进程时可以直接调用daemom接口进行创建,daemom函数的函数原型如下:

int daemon(int nochdir, int noclose);

参数说明:

  • 如果参数nochdir为0,则将守护进程的工作目录该为根目录,否则不做处理。
  • 如果参数noclose为0,则将守护进程的标准输入、标准输出以及标准错误重定向到/dev/null,否则不做处理。
#include <iostream>
#include <unistd.h>
#include <string>const std::string filename = "/dev/null";// 守护进程化
int main()
{daemon(0, 0);// 死循环,守护进程是不退的while (true);return 0;
}

调用daemon函数创建的守护进程与我们原生创建的守护进程差距不大


模拟实现daemon函数

有了上述创建守护进程的代码,要模拟实现daemon函数就很容易了,我们只需要设置两个参数nochdir和noclose,当所给nochdir为0时,我们将守护进程的工作目录该为根目录,当所给noclose为0时,我们则将守护进程的标准输入、标准输出以及标准错误重定向到/dev/null即可。

#include <iostream>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string>const std::string filename = "/dev/null";// 守护进程化
void Daemom(const std::string &Chdir)
{// 1.屏蔽信号signal(SIGCLD, SIG_IGN);signal(SIGPIPE, SIG_IGN);signal(SIGSTOP, SIG_IGN);// 2.fork子进程,子进程执行setsid(),创建守护进程,父进程退出if (fork() > 0)exit(0);setsid();// 3.将守护进程的工作路径更改为根目录if(!Chdir.empty()) chdir("/");// 由于守护进程没有终端,不能和用户进程交互,所以我们需要将标准输入,标准输出,标准错误重定向到 /dev/null下int fd = open(filename.c_str(), O_RDWR, 000);if (fd > 0){dup2(fd, 0);dup2(fd, 1);dup2(fd, 2);}// daemon(0, 0);// 死循环,守护进程是不退的while (true);return;
}

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

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

相关文章

Json rpc 2.0比起传统Json在通信中的优势

JSON-RPC 2.0 相较于直接使用传统 JSON 进行通信&#xff0c;在协议规范性、开发效率、通信性能等方面具有显著优势。以下是核心差异点及技术价值分析&#xff1a; 一、结构化通信协议&#xff0c;降低开发成本 传统 JSON 通信需要开发者自定义数据结构和处理逻辑&#xff0c;…

机器学习与人工智能:NLP分词与文本相似度分析

DIY AI & ML NLP — Tokenization & Text Similarity by Jacob Ingle in Data Science Collective 本文所使用的数据是在 Creative Commons license 下提供的。尽管我们已尽力确保信息的准确性和完整性&#xff0c;但我们不对数据的完整性或可靠性做任何保证。数据的使…

RK3568平台OpenHarmony系统移植可行性评估

https://docs.openharmony.cn/pages/v5.0/zh-cn/device-dev/quick-start/quickstart-appendix-compiledform.md 官方给的标准系统就是RK3568, 所以肯定可以, 关于硬件加速部分 看了鸿蒙RK3568开发板的GPU编译配置,只能说能用 https://docs.openharmony.cn/pages/v4.1/zh-cn/…

论文浅尝 | HOLMES:面向大语言模型多跳问答的超关系知识图谱方法(ACL2024)

笔记整理&#xff1a;李晓彤&#xff0c;浙江大学硕士&#xff0c;研究方向为大语言模型 论文链接&#xff1a;https://arxiv.org/pdf/2406.06027 发表会议&#xff1a;ACL 2024 1. 动机 多跳问答&#xff08;Multi-Hop Question Answering, MHQA&#xff09;技术近年来在自然语…

机器学习中的特征工程:解锁模型性能的关键

在机器学习领域&#xff0c;模型的性能往往取决于数据的质量和特征的有效性。尽管深度学习模型在某些任务中能够自动提取特征&#xff0c;但在大多数传统机器学习任务中&#xff0c;特征工程仍然是提升模型性能的关键环节。本文将深入探讨特征工程的重要性、常用方法以及在实际…

Kotlin与Java的融合趋势:从互操作到云原生实践

在2025年的软件开发领域&#xff0c;Kotlin和Java作为JVM生态的支柱语言&#xff0c;展现出强大的协同能力。Kotlin以其简洁的语法和现代特性迅速崛起&#xff0c;而Java凭借其成熟生态和稳定性依然占据主导地位。通过两者的融合&#xff0c;我们的实时聊天系统将开发效率提升了…

Python生成器:高效处理大数据的秘密武器

生成器概述 生成器是 Python 中的一种特殊迭代器&#xff0c;通过普通函数的语法实现&#xff0c;但使用 yield 语句返回数据。生成器自动实现了 __iter__() 和 __next__() 方法&#xff0c;因此可以直接用于迭代。生成器的核心特点是延迟计算&#xff08;lazy evaluation&…

Flask框架入门与实践

Flask框架入门与实践 Flask是一个轻量级的Python Web框架&#xff0c;以其简洁、灵活和易于上手的特点深受开发者喜爱。本文将带您深入了解Flask的核心概念、基本用法以及实际应用。 什么是Flask&#xff1f; Flask是由Armin Ronacher于2010年开发的微型Web框架。与Django等…

数学复习笔记 14

前言 和家里人交流了一下&#xff0c;他们还是希望我全力以赴初试&#xff0c;我确实也得放开了干&#xff0c;不要束手束脚的。好好加油。感觉公共课都没有啥压力&#xff0c;主要是专业课要好好加油&#xff0c;真不能过不了线&#xff0c;要是过不了线&#xff0c;啥都白搭…

金格iWebOffice控件在新版谷歌Chrome中不能加载了怎么办?

金格iWebOffice控件是由江西金格网络科技有限责任公司开发的中间件软件&#xff0c;主要用于在浏览器中直接编辑Word、Excel、PowerPoint等Office文档&#xff0c;曾经是一款优秀国产的WebOffice插件。 由于2022年Chrome等浏览器取消支持PPAPI接口&#xff0c;导致这款金格iWe…

ChatGPT 能“记住上文”的原因

原因如下 你把对话历史传给了它 每次调用 OpenAI 接口时&#xff0c;都会把之前的对话作为参数传入&#xff08;messages 列表&#xff09;&#xff0c;模型“看见”了之前你说了什么。 它没有长期记忆 它不会自动记住你是谁或你说过什么&#xff0c;除非你手动保存历史并再次…

微信小程序van-dialog确认验证失败时阻止对话框的关闭

使用官方(Vant Weapp - 轻量、可靠的小程序 UI 组件库)的before-close&#xff1a; wxml&#xff1a; <van-dialog use-slot title"名称" show"{{ show }}" show-cancel-button bind:cancel"onClose" bind:confirm"getBackInfo"…

K8S Ingress、IngressController 快速开始

假设有如下三个节点的 K8S 集群&#xff1a; ​ k8s31master 是控制节点 k8s31node1、k8s31node2 是工作节点 容器运行时是 containerd 一、理论介绍 1&#xff09;什么是 Ingress 定义&#xff1a;Ingress 是 Kubernetes 中的一种资源对象&#xff0c;它定义了外部访问集群内…

Vue3 + Element Plus 动态表单实现

完整代码 <template><div class"dynamic-form-container"><el-formref"dynamicFormRef":model"formData":rules"formRules"label-width"auto"label-position"top"v-loading"loading"&g…

Mac修改hosts文件方法

Mac修改hosts文件方法 在 macOS 上修改 hosts 文件需要管理员权限 步骤 1&#xff1a;打开终端 通过 Spotlight 搜索&#xff08;Command 空格&#xff09;输入 Terminal&#xff0c;回车打开。或进入 应用程序 > 实用工具 > 终端。 步骤 2&#xff1a;备份 hosts 文件…

深度学习—BP神经网络

文章目录 [TOC](文章目录) 一、基本概念二、 网络结构三、BP神经网络的原理总结特点&#xff1a;应用场景优缺点 一、基本概念 BP 神经网络&#xff08;Backpropagation Neural Network&#xff09;是一种基于误差反向传播算法的多层前馈神经网络&#xff0c;由输入层、隐藏层…

Spring AI(6)——向量存储

向量数据库是一种特殊类型的数据库&#xff0c;在 AI 应用中发挥着至关重要的作用。 在向量数据库中&#xff0c;查询与传统关系型数据库不同。它们执行的是相似性搜索&#xff0c;而非精确匹配。当给定一个向量作为查询时&#xff0c;向量数据库会返回与该查询向量“相似”的…

Qt功能区:简介与安装

Qt功能区 1. 功能区简介2. SARibbon2.1 简介2.2 编译与安装采用CMake-gui进行编译采用VS进行编译安装与使用 Qt 官方不支持 Ribbon 风格&#xff08;Ribbon UI 风格是微软开创的&#xff0c;具有专利许可协议&#xff0c;许可协议对从构建 UI 的指令到每个按钮间的空格数都做了…

iOS safari和android chrome开启网页调试与检查器的方法

手机开启远程调试教程&#xff08;适用于 Chrome / Safari&#xff09; 前端移动端调试指南&#xff5c;适用 iPhone 和 Android&#xff5c;WebDebugX 出品 本教程将详细介绍如何在 iPhone 和 Android 手机上开启网页检查器&#xff0c;配合 WebDebugX 实现远程调试。教程包含…

Golang企业级商城高并发微服务实战

Golang企业级商城高并发微服务实战包含内容介绍&#xff1a; 从零开始讲了百万级单体高并发架构、千万级微服务架构&#xff0c;其中包含Rpc实现微服务、微服务的跨语言调用jsonrpc和protobuf、protobuf的安装、protobuf高级语法、protobuf结合Grpc实现微服务实战、微服务服务…