linux进程管理,一个进程的一生(喂饭级教学)

这篇文章谈谈linux中的进程管理

一周爆肝,创作不易,望支持!

希望对大家有所帮助!记得收藏

要理解进程管理,重要的是周边问题,一定要知其然,知其所以然。看下方目录就知道都是干货!

目录

1.什么是进程管理?

2.为什么要有进程管理?

3.如何对进程进行管理?

(1)描述进程

(2)组织进程

4.查看系统中的进程

(1)命令查看

(2)文件查看

5.创建进程的两种方式

(1)./运行一个程序

(2)通过代码创建

6.父子进程与fork()

(1)父子关系

(2)系统调用fork()

(3)fork()原理

1.fork()干了什么事?

2.为什么fork()会有两个返回值?

3.为什么fork()给父进程返回子进程pid,给子进程返回0?

4.fork()之后,父子进程谁先运行?

5.如何理解同一个变量会有不同的值?

6.重新理解fork()

7.进程状态

(1)一般操作系统的进程状态

1.运行状态

2.阻塞状态

3.阻塞挂起和swap分区

(2)linux的进程状态

linux进程的休眠状态

linux僵尸进程和孤儿进程

8.进程状态切换

CUP运行队列中的进程如何调度?

9.进程的性质

1.进程的竞争性

2.进程的独立性

3.进程的并行、并发

10.进程的优先级和时间片

11.进程间切换

12.linux内核2.61CPU运行队列窥视(综合理解!)


1.什么是进程管理?

OS内核中有内存管理,进程管理,文件管理,驱动管理,OS将这四样管理起来才基本可以实现硬件和数据的自由调控,才可成为一个优质内核。

2.为什么要有进程管理?

要知道为什么要有进程管理,首先要知道进程是什么东西,这里给出进程的定义

进程的定义程序的一个执行实例,加载到内存中的程序,即正在执行的程序。进程是操作系统执行任务的基本单元,也是分配资源、处理数据和被调度的基本单元。更加通俗的理解:操作系统要做事情,进程就是一件又一件的"事情"

3.如何对进程进行管理?

在哲学的范畴,管理的本质对数据的管理,而非对具体对象的管理管理的策略是先描述,再组织。即先将被管理对象进行建模描述为抽象类型,再想好如何将每个被管理对象组织起来。

操作系统对进程的管理也是如此:

描述进程、组织进程

(1)描述进程

在操作系统中,经常将描述进程的类称为PCB(process control block)。进程的属性有很多:比如pid,ppid(父进程pid),stat(进程状态),进程优先级等等。后续慢慢学习······

struct PCB
{int pid;int ppid;int stat;......
};

(2)组织进程

进程的组织就是用高效的数据结构将进程对象组织起来,操作系统一般用双向链表将进程的PCB对象组织起来

4.查看系统中的进程

(1)命令查看

ps ajx //查看当前所有进程
ps ajx | head -1 && ps ajx | grep mybin//查看指定进程mybin

(2)文件查看

根目录下的proc目录中有当前存在的所有进程,因此这个目录是动态的。

这个目录里的各个数字目录,就是以各个进程的pid命名的。目录里面放的就是进程PCB对象的各种属性。 

5.创建进程的两种方式

(1)./运行一个程序

本质将磁盘上的可执行程序代码和数据拷贝到内存当中,为这个进程创建PCB对象,将PCB对象链入内存中管理PCB对象的双链表中(重点)

(2)通过代码创建

使用fork()函数创建当前进程的子进程。

6.父子进程与fork()

(1)父子关系

进程是有父子关系的,在一个进程中创建出新的进程,这个新的进程就被叫做那个进程的子进程。那个进程叫做新的进程父进程

(2)系统调用fork()

fork()是一个进程通过代码创建子进程的时候,所调用的系统接口。通过fork()函数,在fork()下一行处会创建一个子进程,这个子进程和父进程共同执行接下来的代码

如图:

./mybin运行之后 

体现出了fork()之后, 子进程和父进程两个执行流分别执行接下来的代码。

fork()函数

头文件#include<unistd.h>

返回值:父进程返回子进程pid,子进程返回0。

(3)fork()原理

1.fork()干了什么事?

现象:fork()是系统接口,fork()之后会为父进程创建子进程,父子进程两个执行流共同执行fork()之后的代码。

本质:进程的创建,本质是将可执行程序代码和数据加载到内存中,创建PCB对象,再将PCB对象链接到管理PCB对象的双向链表中。父进程中使用fork()创建进程本质是以父进程PCB为模板创建子进程PCB,由于子进程没有从磁盘中加载代码和数据,子进程的PCB只能指向父进程的代码和数据,因此父子进程共享代码子进程可以看到父进程的全部代码,由于进程的独立性,数据会以写时拷贝的方式给到子进程。

2.为什么fork()会有两个返回值?

fork()函数在return x 之前,子进程就被创建出来了,所以不要把fork()看成一个整体,return之后父子进程两个执行流共同执行接下来的代码,return也被父子进程以不同的值返回两次

3.为什么fork()给父进程返回子进程pid,给子进程返回0?

给父进程返回子进程的pid,是为了让父进程较好的控制管理子进程,所以返回子进程的pid让父进程进行控制。子进程只需要确认自己创建成功与否,所以返回0。

4.fork()之后,父子进程谁先运行?

fork()后,父子进程都会进入CPU的执行队列中被调度,需要依赖进程PCB的调度优先级和调度器算法。

5.如何理解同一个变量会有不同的值?

父子进程共享代码,但是要保证进程的独立性数据不能共享,所以数据会以写时拷贝的方式拷贝给子进程,return两个值本质是写两次数据,子进程的数据就要写时拷贝。因此父子进程都有自己存储返回值的变量。

6.重新理解fork()

7.进程状态

(1)一般操作系统的进程状态

进程的状态指的是一个进程处在内存中某个PCB队列中所体现出来的状态。进程的状态是为了更好的让操作系统得知每个进程的实时情况所设定的。进程可以在很多PCB队列中进行排队。进程状态是PCB中的一个属性,是一个int类型的值,来表示这个进程目前的状态

1.运行状态

我们把进程的PCB在CPU的运行队列中排队的状态认定为运行状态。在CPU运行队列的进程准备被调度(取决于调度器算法)。

2.阻塞状态

当我们的进程在CPU的运行队列中被调度的时候,这个进程开始让CPU来执行它的可执行程序,这个可执行程序势必或多或少会访问到操作系统中的软硬件资源,如果此时要访问的软硬件资源还没有到位,那么这个进程的PCB就会从CPU的运行队列上剥离,去到软硬件资源的等待队列中排队,此时这个进程的状态被设置为阻塞状态

3.阻塞挂起和swap分区

硬件阻塞

当我们的进程处于阻塞状态,进程的PCB在对应软硬件资源的等待队列中排队,此时这个进程的代码数据和PCB都在内存中占用着资源,但是这个进程暂时不需要被调度,如果此时操作系统的内存资源严重不足,就会把这个进程的代码和数据交换到磁盘中的swap分区中,为内存腾出空间。此时进程就处于阻塞挂起状态。当软硬件资源就绪时,操作系统再把这部分代码和数据唤回内存中,此时进程再从软硬件资源的等待队列中剥离到CPU的运行队列中排队。

软件阻塞

用linux调试代码工具gdb来解释一下就是,gdb在调试程序的过程中要根据断点来追踪、暂停进程,要想调试一个程序的代码,gdb和这个程序必须都加载到内存当中成为进程,CPU执行代码遇到断点进程就被阻塞了,需要等待gdb这个进程的继续操作,此时这个进程就需要等待软件资源gdb的响应,而gdb又要等待诸如键盘的响应,所以进程的PCB到gdb这个进程的PCB里的等待队列里排队,gdb这个进程PCB又到键盘的等待队列里排队。当键盘响应gdb,gdb的PCB又到CPU的运行队列里排队,待调试代码的进程也到CPU的运行队列里排队。

(2)linux的进程状态

linux进程状态主要有一下几种:

static const char * const task_state_array[] =
{"R (running)", /* 0 */  //运行状态"S (sleeping)", /* 1 */   //休眠状态"D (disk sleep)", /* 2 */   //深度休眠状态"T (stopped)", /* 4 */    //暂停状态"t (tracing stop)", /* 8 */   //追踪暂停状态"X (dead)", /* 16 */    //死亡状态"Z (zombie)", /* 32 */   //僵尸状态
};
linux进程的休眠状态

本质就是阻塞状态(可以随时被终止)。这里还有一个深度休眠状态disk sleep(磁盘休眠)当一个进程在向磁盘上写入数据的时候,这个进程需要等待磁盘写入完毕,并把写入结果返回给进程PCB,由于这个过程中进程不可被终止(防止数据丢失)此时这个进程的状态就是深度休眠状态。

linux僵尸进程和孤儿进程

当一个进程的可执行程序已经在CPU上跑完了,这个进程的生命周期就结束了,此时操作系统会先将这个进程的代码和数据进行释放,暂时不会释放这个进程的PCB。为什么?由于进程退出时的退出信息会保存在进程的PCB中,而操作性系统或者父进程要得知进程的退出原因(任务完成情况),所以要在父进程或者操作系统读取到退出信息之后,进程才能完全销毁,将进程PCB也释放。linux规定:进程在退出后,进程的PCB还没有被父进程或者操作系统读取到,进程还没有完全退出的进程状态僵尸状态。如果进程一直处于僵尸状态,会导致内存泄露的问题。

上面所说,进程在退出时,PCB是由父进程来回收的。那么,如果进程退出前,父进程就已经退出了,那这个进程的PCB就没有相应的进程来回收了,此时进程的状态成为孤儿状态

8.进程状态切换

切换本质 : 进程的状态切换,本质就是进程的PCB不同队列中做不停的跳转

CUP运行队列中的进程如何调度?

9.进程的性质

1.进程的竞争性

系统进程众多,而CPU资源只有少数,甚至一个,所以进程之间是具有竞争属性的。为了高效完成任务,合理竞争相关资源,便有了进程优先级和时间片已经调度器算法。

2.进程的独立性

各个进程运行期间互不干扰,各自独立。

3.进程的并行、并发

并行:多个进程分别在多个CPU上同时运行。

并发:多个进程在单个CPU上采取进程切换的方式,在一段时间内让多个进程都得以推进。

不要用人的感知来感受CPU的处理速度,例如每个进程的时间片是0.0001秒,CPU就执行每个进程0.0001秒,在一秒的时间内,上百个进程,每个都被CPU推进了100次!CPU的运行速度之快,决定了进程并发的可行性。

10.进程的优先级和时间片

linux进程的优先级范围是60-99,默认优先级为80。优先级由默认优先级和nice值共同决定,例如:创建一个进程,这个进程的默认优先级为80,同时把nice设置为10,进程的最终优先级为80+nice=90。

时间片决定了一个进程每次使用CPU资源的最大时间限度。当一个进程使用CPU资源的时间超过时间片,进程就会自动剥离,等待下次被调度。

11.进程间切换

进程间切换指的是进程PCB在CPU运行队列中,上、下的反复过程。下去的进程要打包带走自己的寄存器数据,上来的进程要将自己的寄存器数据拷贝给寄存器硬件

12.linux内核2.61CPU运行队列窥视(综合理解!)

现在执行一个可执行程序mybin。

./mybin

 一个进程的一生开始了!

1.此时,操作系统在内存中创建这个可执行程序的PCB,并把磁盘上的代码和数据拷贝到内存中。

2.PCB放入CPU运行队列中的过期队列中等待被调度。需要等待活跃队列中的PCB全部剥离,PCB剥离需要同时带走自己的寄存器数据保存在自己的PCB中。

3.活跃队列中的PCB全部剥离,swap两队列的指针,开始按照优先级执行活跃队列(原过期队列)中的进程。每个进程让CPU执行,需要把PCB内的寄存器数据拷贝给寄存器。

4.该你执行了,CPU开始执行代码,代码中要访问软硬件资源但没有就绪,阻塞!PCB进入对应的等待队列。(剥离时带走自己的寄存器数据)

5.软硬件资源就绪,PCB被唤回CPU运行队列中的过期队列中等待被调度。

6.又轮到你了,将寄存器数据交给寄存器,继续从上次阻塞的地方开始执行。

7.时间片到了,剥离到过期队列中。

8.活跃队列中的PCB全部剥离,再swap两队列的指针。CPU开始执行过期队列中的进程。

9.又轮到你了,这次CPU在时间片结束时间内把代码执行完了,进程将要结束了。

10.父进程把你的代码和数据释放,将PCB内的退出数据读取完毕,把PCB也释放。进程Z状态。

本次分享就到这里,如果对大家有用的话,希望程序猿们可以三连支持一下,会继续分享知识,加油!

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

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

相关文章

MD5生成和校验

MD5生成和校验 2021年8月19日席锦 任何类型的一个文件&#xff0c;它都只有一个MD5值&#xff0c;并且如果这个文件被修改过或者篡改过&#xff0c;它的MD5值也将改变。因此&#xff0c;我们会对比文件的MD5值&#xff0c;来校验文件是否是有被恶意篡改过。 什么是MD5&#xff…

cmd命令快速打开MATLAB

文章目录 复制快捷方式添加 -nojvm打开 复制快捷方式 添加 -nojvm 打开 唯一的缺点是无法使用plot&#xff0c;这一点比不上linux系统&#xff0c;不过打开速度还是挺快的。

Java面试(基础篇)——解构Java常见的基础面试题 结合Java源码分析

fail-safe 和fail-fast机制分别有什么作用&#xff1f; Fail-fast&#xff1a;快速失败 Fail-fast &#xff1a; 表示快速失败&#xff0c;在集合遍历过程中&#xff0c;一旦发现容器中的数据被修改了&#xff0c;会立刻抛出ConcurrentModificationException 异常&#xff0c…

如何学会从产品经理角度去思考问题?

如何学会从产品经理角度去思考问题&#xff1f; 从产品经理的角度思考问题意味着你需要关注产品从构思到上市全过程中的各个方面&#xff0c;包括用户需求、市场趋势、设计、开发、测试、上市后的用户反馈等。以下是一些策略和方法&#xff0c;帮助你培养从产品经理角度思考问…

Python爬虫:ad广告引擎的模拟登录

⭐️⭐️⭐️⭐️⭐️欢迎来到我的博客⭐️⭐️⭐️⭐️⭐️ &#x1f434;作者&#xff1a;秋无之地 &#x1f434;简介&#xff1a;CSDN爬虫、后端、大数据领域创作者。目前从事python爬虫、后端和大数据等相关工作&#xff0c;主要擅长领域有&#xff1a;爬虫、后端、大数据…

Mybatis 相关模块以及设计模式分析

一、缓存模块 MyBatis作为一个强大的持久层框架&#xff0c;缓存是其必不可少的功能之一&#xff0c;Mybatis中的缓存分为一级缓存和二级缓存。但本质上是一样的&#xff0c;都是使用Cache接口实现的。缓存位于 org.apache.ibatis.cache包下。 通过结构我们能够发现Cache其实使…

螺杆支撑座是如何维持精度和稳定性的?

螺杆支撑座是机械设备中重要的支撑元件&#xff0c;主要用于支撑和固定螺杆&#xff0c;以确保其精度和稳定性&#xff0c;以下是螺杆支撑座在实际使用中的优势&#xff1a; 1、良好的耐腐蚀性&#xff1a;螺杆支撑座通常采用防腐蚀材料制造&#xff0c;能够抵抗各种腐蚀性介质…

linux安装visual studio code

下载 https://code.visualstudio.com/ 下载.deb文件 安装 假如文件被下载到了 /opt目录下 进入Opt目录&#xff0c;右键从当前目录打开终端。 输入下面的安装命令。 sudo apt-get install ./code_1.83.1-1696982868_amd64.deb 安装成功。 配置 打开 visual studio cod…

【蓝桥每日一题]-动态规划 (保姆级教程 篇11)#方格取数2.0 #传纸条

目录 题目&#xff1a;方格取数 思路&#xff1a; 题目&#xff1a;传纸条 思路&#xff1a; 题目&#xff1a;方格取数 &#xff08;跑两次&#xff09; 思路&#xff1a; 如果记录一种方案后再去跑另一个方案&#xff0c;影响因素太多了&#xff0c;所以两个方案要同时开…

手搭手Ajax经典基础案例省市联动

环境介绍 技术栈 springbootmybatis-plusmysql 软件 版本 mysql 8 IDEA IntelliJ IDEA 2022.2.1 JDK 1.8 Spring Boot 2.7.13 mybatis-plus 3.5.3.2 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http:/…

分类预测 | MATLAB实现SSA-CNN-BiLSTM-Attention数据分类预测(SE注意力机制)

分类预测 | MATLAB实现SSA-CNN-BiLSTM-Attention数据分类预测&#xff08;SE注意力机制&#xff09; 目录 分类预测 | MATLAB实现SSA-CNN-BiLSTM-Attention数据分类预测&#xff08;SE注意力机制&#xff09;分类效果基本描述模型描述程序设计参考资料 分类效果 基本描述 1.MAT…

认识哈希表和哈希表的实现

哈希函数的定义&#xff1a; out f(in) 1&#xff09;in -> ∞&#xff0c; out -> S 输入域是无穷的&#xff0c;输出域是有限的&#xff0c;也就是S域&#xff1b; 2&#xff09;相同的输入一定会得到相同的输出&#xff1b; 3&#xff09;不同的输入可能会有相同…

Swift 判断 A B 两个时间是不是同一天,A 是不是 B 的昨天

1. 今天要做这个效果&#xff08;在时间旁边显示今天&#xff0c;昨天&#xff09; 2. Preview 3. Code: // 添加 今天 昨天 func show_today_yesterday(d: Date Date()) -> String {let calendar Calendar.currentlet today: Date Date()if calendar.isDate(today, inS…

C++DAY50

源文件代码 #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);if(!db.contains()){db QSqlDatabase::addDatabase("QSQLITE");db.setDatabaseName(&q…

QTday05(TCP的服务端客户端通信)

实现聊天室功能 服务端代码&#xff1a; pro文件需要导入 network 头文件&#xff1a; #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTcpServer>//服务端 #include <QTcpSocket>//客户端 #include <QList> #include <QMes…

超声波清洗机频率如何选择?高频和低频有什么区别

超声波清洗原理就是在清洗液中产生“空化效应”&#xff0c;即清洗液产生拉伸和压缩现象&#xff0c;清洗液拉伸时会产生大量微小气泡&#xff0c;清洗液压缩时气泡会被压碎破裂。这些气泡产生和破裂的局部压强可达到上千个大气压的冲击力&#xff0c;这种极强大的压力足以使得…

Leetcode 1089. 复写零

复写零 题目链接1089. 复写零 给你一个长度固定的整数数组 arr &#xff0c;请你将该数组中出现的每个零都复写一遍&#xff0c;并将其余的元素向右平移。 注意&#xff1a;请不要在超过该数组长度的位置写入元素。请对输入的数组 就地 进行上述修改&#xff0c;不要从函数返回…

网络协议--UDP:用户数据报协议

11.1 引言 UDP是一个简单的面向数据报的运输层协议&#xff1a;进程的每个输出操作都正好产生一个UDP数据报&#xff0c;并组装成一份待发送的IP数据报。这与面向流字符的协议不同&#xff0c;如TCP&#xff0c;应用程序产生的全体数据与真正发送的单个IP数据报可能没有什么联…

一分钟带你了解什么是0day攻击什么是Nday攻击

1. 什么是零日漏洞 零日攻击是指利用零日漏洞对系统或软件应用发动的网络攻击。 零日漏洞也称零时差漏洞&#xff0c;通常是指还没有补丁的安全漏洞。由于零日漏洞的严重级别通常较高&#xff0c;所以零日攻击往往也具有很大的破坏性。目前&#xff0c;任何安全产品或解决方案…

吃瓜教程2|线性模型

线性回归 “广义的线性模型”&#xff08;generalized linear model&#xff09;&#xff0c;其中&#xff0c;g&#xff08;*&#xff09;称为联系函数&#xff08;link function&#xff09;。 线性几率回归&#xff08;逻辑回归&#xff09; 线性判别分析 想让同类样本点的…