【Linux系统】认识操作系统和操作系统如何进行管理以及进程相关状态
进程概念
- 1 认识冯诺依曼体系结构
- 1.1 冯诺依曼体系结构存储器的作用
- 2 操作系统(Operator System,OS)
- 2.1 OS如何进行管理
- 3 进程
- 3.1 OS管理进程:先描述再组织
- 3.2 描述进程-PCB
- 3.3 查看进程
- 3.4 通过系统调用获取进程标识符
- 3.5 通过系统调用创建子进程——fork
- 4 进程状态
- 4.1 进程阻塞
- 4.2 挂起状态
- 4.3 僵尸(zombie)状态
- 4.4 孤儿进程
本篇文章所涉及到的内容主要是与 进程的基础概念相关,所涉及到的内容有
1认识冯诺依曼系统
2操作系统的概念与定位
3深入了解进程概念,了解PCB
4会学习到进程状态和创建进程,僵尸进程和孤儿进程,及其形成的原因和危害
1 认识冯诺依曼体系结构
我们的计算机大部分都遵循冯诺依曼体系结构
冯诺依曼体系结构如下图所示
这里的输入设备可以是:键盘,话筒,摄像头,鼠标,网卡,磁盘等
存储器就是我们的内存
输出设备可以是:显示器,磁盘,网卡,声卡音响等
中央处理器部分就是我们常说的CPU
1.1 冯诺依曼体系结构存储器的作用
我们首先要知道,我们的输入输出设备通常称之为外设,而这些外设一般会运行得比较慢,以磁盘为例相对于内存,磁盘运行是比较慢的。
而我们的CPU运行是最快的。
这里要讨论的是冯诺依曼体系结构中存储器的作用,我们尝试去掉存储器。
这种可以运行吗?答案是可以的。
但是比起冯诺依曼体系结构,效率差的太远了。
因为我们前面说过,外设的运行是最慢的,而CPU运行的效率虽然快,但是外设的运行效率拖慢了CPU的运行效率。换句话就是,我输入设备都还没读进来,CPU运行得再快也没用,CPU怎么处理?
所以,我们可以得出大致的一个结论:
冯诺依曼体系结构中的存储器可以更好地提升整个体系的运行效率。
因为有了内存的存在,我们的计算机就可以对数据做预加载,CPU在进行数据计算时,就可以不用访问外设,直接与内存联系即可。
外设要输入输出数据,也只能写入内存或从内存中读取
2 操作系统(Operator System,OS)
操作系统是一款进行软硬件资源管理的软件
操作系统对下通过管理好软硬件资源,对上给提供良好的(安全,稳定,高效,功能丰富等)的执行体验。
如图所示,操作系统对外会表现为一个整体,但是会暴露自己的部分接口,供上层开发使用,这部分由操作系统的提供的接口,叫做系统调用。
系统调用在使用上,功能比较基础,对用户的要求相对也比较高,所以,有心的开发者可以对部分系统调用进行适度封装,从而形成库,有了库,就很有利于更上层用户或者开发者进行二次开发。
2.1 OS如何进行管理
OS管理的手段是:先描述再组织
什么意思呢?我们要先知道这里的管理的本质是指对被管理对象的数据进行管理
也就说,OS是先将所有被管理对象的数据收集起来(先描述),然后再放在相应的数据结构里面(再组织),以方便进行后续的操作。
3 进程
什么是进程?
我们通常说进程是程序的一个执行实例。一个正在执行的程序等
站在内核的角度来说:进程是担当分配系统资源(CPU时间,内存)的实体
3.1 OS管理进程:先描述再组织
我们任何启动程序的行为,都由操作系统帮助我们将程序转换为进程,完成特定的任务。
OS如何管理进程?
还是先描述再组织
3.2 描述进程-PCB
进程控制块(PCB,Process Control Block),进程信息被放在这样的数据结构中,可以理解为进程属性的集合。
Linux操作系统的下的PCB是:task_struct
task_struct是Linux内核的一种数据结构,它会被装载到RAM(内存)里并且包含着进程的信息。
所以 进程 = 内核关于进程的相关数据结构 + 当前的代码和数据
3.3 查看进程
进程的信息可以通过/proc系统文件夹查看
如:要获取PID为1的进程信息,你需要查看/proc/1这个文件夹
大多数进程信息同样可以使用top和ps这些用户级工具来获取
我们写出这样一段C语言代码并运行它
输入
ps axj | head -1 && ps ajx | grep xxx| grep -v grep//xxx是可执行文件名称
即可查看该程序的进程
3.4 通过系统调用获取进程标识符
每个进程都会有对应的PID(进程id),也会有PPID(父进程id)
我们反复运行可以看到,每次运行,该程序的PID都不同,而父进程的ID都是一样的。
这里的父进程其实是bash,我们输入以下命令查看2707进程信息
ps axj | head -1 && ps ajx | grep 2707
这里说明了bash命令行解释器,本质上也是一个进程
3.5 通过系统调用创建子进程——fork
我们运行一下这段代码:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{int ret = fork();printf("hello proc : %d!, ret: %d\n", getpid(), ret);sleep(1);return 0;
}
我们发现会发现打印了两行,说明该程序利用fork()创建了两个进程,而且是父子进程的关系。
fork有两个返回值
父子进程代码共享,数据各自开辟空间,私有一份(采用写时拷贝)
fork 之后通常要用 if 进行分流
当fork返回值是0时,是子进程。
fork返回值大于0时,是父进程。
我们写一段代码验证一下:
可以明显地看到,fork出来的两个进程确实是父子进程的关系。
子进程的ppid一直都是父进程的pid,父进程的ppid也一直是bash的pid
4 进程状态
进程除了运行状态,还会有其他的状态。
我们看一下下面的状态在kernel源代码里的定义
/*
* The task state array is a strange "bitmap" of
* reasons to sleep. Thus "running" is zero, and
* you can test for combinations of others with
* simple bit tests.
*/
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 */
};
R运行状态(running):其实运行状态并不代表该进程一定在运行中,它表明进程要么是在运行中或者是在运行队列里。因为在CPU在计算进程时,是将多个进程快速切换并逐一运行的,不是同时运行的,多个进程像队列一样排好队等待CPU计算。因为快速切换的时间非常短,所以我们人很难感觉到。
S睡眠状态(sleeping):意味着程序在等待事件的完成。(这里的睡眠有时候也叫做可中断睡眠)(interruptible sleep)。这里的睡眠状态,本质上是一种阻塞状态。
D磁盘休眠状态(Disk sleep)有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的进程通常会等待IO的结束。
T停止状态(stopped): 可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行。
X死亡状态(dead):这个状态只是一个返回状态,你不会在任务列表里看到这个状态。
4.1 进程阻塞
进程阻塞是一种因为要等待某种条件就绪,而导致的一种不可推进的状态。
说的简单一点,就是该进程需要某种资源才能运行,否则就会卡住。
CPU要处理大量的进程,上面说过,OS要做进程进行管理,管理方式就是先描述,再组织。而我们的PCB可以被维护在不同的队列中,这些队列中都是一个个要被运行的进程,正在排队等待运行的进程的状态,可以看成阻塞状态。或者拿我们的外设键盘来说,如果我们执行了一个需要我们输入后才能运行的程序,在程序等待我们输入的过程中,这个过程就是阻塞状态,并不是运行状态。OS会创建一个相应的结构体task_struct去描述并组织管理这个进程。
所以阻塞就是不被调度,一定是因为当前进程需要某种资源,进程task_struct结构体需要在某种被OS管理的资源下排队。
4.2 挂起状态
前面我们说过,当进程阻塞时就是不被CPU调度,那么此时该进程会在内存里面占有一定的空间,如果这种进程非常多的话就会影响正常的进程运行,所以我们的OS会把这种不被调度的进程的代码和数据放在磁盘中,这种状态就叫做挂起状态,也可以说挂起阻塞状态。
4.3 僵尸(zombie)状态
僵尸状态(Z状态)可以和死亡状态(X状态)联系起来。
如果一个进程退出了,那么它会马上进入X状态,立即退出,那么由于写时拷贝的原因,我们的父进程可能会没有机会拿到子进程的退出结果。所以Linux当进程退出的时候,一般进程不会立即进入X状态,而是要维持Z状态,方便后续父进程或者OS读取该子进程退出的结果。
僵尸进程的危害:可能会造成内存泄漏。
一个进程的退出状态要一直被维持下去,直到父进程读取它的信息。如果父进程一直没有读取它的信息,那么该子进程就会一直维持僵尸状态。维护退出状态本身就是要用数据维护,也属于进程的基本信息,所以保存在PCB中,Z进程不退出,PCB要一直维护,如果有大量的这种不被读取信息的进程,不被回收,就会造成内存资源的浪费,导致内存泄漏。
如果在没有特殊要求的情况,一个父进程结束后,会被bash回收,所以我们一般不会直接看到Z状态。
4.4 孤儿进程
如果一个父进程退出,而它的子进程还在,这个子进程会自动被1号进程领养(这个1号进程就是我们的OS),1号进程成为这个子进程的父进程,这种被领养的进程就叫做孤儿进程。
如果没有这种领养机制,那么子进程后续在退出的时候就没有父进程可以回收了,可能会浪费掉内存,这是不被OS认可的,所以OS会领养这种没有父进程的子进程。
相关文章:

【Linux系统】认识操作系统和操作系统如何进行管理以及进程相关状态
进程概念1 认识冯诺依曼体系结构1.1 冯诺依曼体系结构存储器的作用2 操作系统(Operator System,OS)2.1 OS如何进行管理3 进程3.1 OS管理进程:先描述再组织3.2 描述进程-PCB3.3 查看进程3.4 通过系统调用获取进程标识符3.5 通过系统调用创建子进程——for…...

【0基础学爬虫】爬虫基础之HTTP协议的基本原理介绍
大数据时代,各行各业对数据采集的需求日益增多,网络爬虫的运用也更为广泛,越来越多的人开始学习网络爬虫这项技术,K哥爬虫此前已经推出不少爬虫进阶、逆向相关文章,为实现从易到难全方位覆盖,特设【0基础学…...

SpringBoot 整合定时任务
注解概览 EnableScheduling 在配置类上使用,开启计划任务的支持(类上) Scheduled 来申明这是一个任务,包括cron,fixDelay,fixRate等类型(方法上,需先开启计划任务的支持) pom依赖 <parent…...

我的零分周赛:CSDN周赛第30期,成绩“0”分,天然气定单、小艺读书、买苹果、圆桌
CSDN周赛第30期,成绩“0”分,天然气定单、小艺读书、买苹果🍎、圆桌。 (本文获得CSDN质量评分【91】)【学习的细节是欢悦的历程】Python 官网:https://www.python.org/ Free:大咖免费“圣经”教程《 python 完全自学教…...

二、Java虚拟机的基本结构
Java虚拟机的架构1.内存结果概述2.类加载器子系统的作用3. 类加载器ClassLoader角色4.类的加载过程5.类加载器的分类1.引导类加载器(虚拟机自带的加载器)Bootstrap ClassLoader2.扩展类加载器(虚拟机自带的加载器) Extenssion ClassLoader3.应用程序类加载器(虚拟机自带的加载器…...

华为OD机试 - 用户调度(Python) | 机试题+算法思路+考点+代码解析 【2023】
用户调度 题目 在通信系统中有一个常见的问题是对用户进行不同策略的调度,会得到不同系统消耗的性能。 假设由N个待串行用户,每个用户可以使用A/B/C三种不同的调度策略。 不同的策略会消耗不同的系统资源,请你根据如下规则进行用户调度,并返回总的消耗资源数。 规则是: …...

HashMap(JDK1.8)源码+底层数据结构分析
HashMap 简介底层数据结构分析 JDK1.8 之前JDK1.8 之后 HashMap 源码分析 构造方法put 方法get 方法resize 方法 HashMap 常用方法测试 感谢 changfubai 对本文的改进做出的贡献! HashMap 简介 HashMap 主要用来存放键值对,它基于哈希表的 Map 接口实现…...

case的使用
1.x和z值 1.1.定义 x:表示不定值 z:表示高阻态,还有一种表达方式“?” 一个x/z可以用来定义十六进制(h)数的4位二进制的状态,八进制(o)数的3位,二进制&#x…...

Mac配置ITerm2
Mac配置ITerm2 install-shell-integration配置lrzsz配置zsh安装Oh-My-Zsh修改皮肤文件加载皮肤添加插件配置profiles 1.expect配置文件2.shell脚本 iterm2顶部白条闪烁 install-shell-integration 安装完成之后会有一个指示标,需要弄掉Preferences > Profiles …...

JUC并发编程(下)
✨作者:猫十二懿 ❤️🔥账号:CSDN 、掘金 、个人博客 、Github 🎉公众号:猫十二懿 学习地址 写在最前 JUC并发编程(上) JUC(Java Util Concurrent)学习内容框架&…...

API接口的基础知识
API是应用程序编程接口(Application Programming Interface)的缩写,能够起到两个软件组件之间的连接器或中介的作用。此类接口往往通过一组明确的协议,来表示各种原始的请求和响应。API文档可以向开发人员展示请求和响应是如何形成…...

基于Spring Boot的教务管理系统
文章目录项目介绍主要功能截图:登录首页学生信息管理班级信息管理教师信息管理教师评价部分代码展示设计总结项目获取方式🍅 作者主页:Java韩立 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题…...

网页扫描图像并以pdf格式上传到服务器端
本文描述如何通过网页驱动扫描仪、高拍仪等图像扫描设备进行图像扫描,扫描结果经编辑修改后以pdf压缩格式上传到后台java程序中进行服务器端落盘保存。图像扫描上传如文字描述顺序所介绍,先要驱动扫描设备工作,进行纸张数据的光学扫描操作形成…...

Airbyte入门
Airbyte 后端技术栈Java 17框架:JerseyAPI: OAS3数据库:PostgreSQL单元和E2E测试:JUnit 5编排:Temporal连接器技术栈连接器可以用任何语言编写。但是,最常见的语言是:Python3.9.0Java 17前端技术…...

研究人员在野外发现大量的信息窃取者 “Stealc “的样本
一个名为Stealc的新信息窃取者正在暗网上做广告,它可能成为其他同类恶意软件的一个值得竞争的对象。 "SEKOIA在周一的一份报告中说:"威胁行为者将Stealc作为一个功能齐全、随时可用的窃取者,其开发依赖于Vidar、Raccoon、Mars和Re…...

数据结构——复杂度讲解(2)
作者:几冬雪来 时间:2023年2月22日 内容:数据结构复杂度讲解 目录 前言: 复杂度讲解(2): 1.空间复杂度是什么: 2.空间复杂度讲解: 结尾: 前言&#x…...

【LeetCode】任务调度器 [M](贪心)
621. 任务调度器 - 力扣(LeetCode) 一、题目 给你一个用字符数组 tasks 表示的 CPU 需要执行的任务列表。其中每个字母表示一种不同种类的任务。任务可以以任意顺序执行,并且每个任务都可以在 1 个单位时间内执行完。在任何一个单位时间&…...

Spring代理模式——静态代理和动态代理
✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...

Anaconda和PyCharm的一些安装问题和命令
今天更新了Windows上的Anaconda到2.3.2,PyCharm到2022.3。 ——发现是纯纯的犯贱orz。出了一堆问题。在这里记录一下供后来者参考。 Anaconda安装 将.\anaconda3\Scripts 和.\anaconda3\Library\bin添加到系统环境变量中。 新建环境的目录在.\anaconda3\envs下 N…...

sql优化建议
对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。 应尽量避免在 where 子句中使用!或<>操作符,否则将引擎放弃使用索引而进行全表扫描。 应尽量避免在 where 子句中对字段进行 null 值判断&a…...

google hacker语句
哎,我就是沾边,就是不打实战( ̄o ̄) . z Z 文章目录前言一、什么是谷歌Docker?二、受欢迎的谷歌docker语句谷歌docker的例子日志文件易受攻击的 Web 服务器打开 FTP 服务器SSH私钥电子邮件列表实时摄像机MP3、电影和 PDF…...

Spring AOP
Spring AOP 文章目录Spring AOP1.概念1.面向切面编程2.AOP的目的3.AOP实现的分类4.AOP 术语2. Spring AOP的特性1.能力与目标2.AOP机制1.理解SpringAOP的代理2.AOP代理类的自调用代码的粒度如何让自调用走代理?3.Enabling AspectJ Support3. 定义切面与切点1. 声明切…...

【消费战略方法论】认识消费者的恒常原理(一):消费者稳态平衡原理
“消费战略”是塔望咨询基于大量的战略与营销实践经验结合心理学、经济学、传播学等相关专业学科的知识应用进行提炼与创造形成的战略方法体系。消费战略强调以消费者为导向,进行企业、品牌战略、品牌营销的制订和落地,企业经营的每个环节和输出的每个动…...

python居然能语音控制电脑壁纸切换,只需60行代码
前言 嗨喽~大家好呀,这里是魔王呐 ❤ ~! 家在日常的电脑使用中,都会有自己喜爱类型的桌面 单纯的桌面有时候会让人觉得单调 今天,就由我带领大家只用60行代码打造一款语音壁纸切换器程序, 让大家能够通过语音的方式来控制电脑去…...

内存泄露定位手段(c语言hook malloc相关方式)
如何确定有内存泄露问题,如何定位到内存泄露位置,如何写一个内存泄漏检测工具? 1:概述 内存泄露本质:其实就是申请调用malloc/new,但是释放调用free/delete有遗漏,或者重复释放的问题。 内存…...

STM32 CAN波特率计算
STM32 CAN波特率计算简介CAN总线收发,中断方式接收配置代码部分reference简介 CAN通信帧共分为数据帧、远程帧、错误帧、过载帧和帧间隔,本文这里以数据帧为例。 显性电平对应逻辑0,CAN_H和CAN_L之差为2.5V左右。而隐性电平对应逻辑1&#x…...

C/C++ 中#define 的妙用,让代码更美一些
C/C 中#define 的妙用,让代码更美一些 flyfish 1 数值类型输出易读的字符串形式 例如使用enum定义一些错误值,想要将数值类型的错误,输出易读的字符串形式 重要的一句代码 #define MAKE_PAIR(val) std::make_pair(val, #val)可以看到 #va…...

Linux文件系统操作与磁盘管理
查看磁盘和目录的容量 使用 df 命令查看磁盘的容量 df在实验楼的环境中你将看到如下的输出内容: 但在实际的物理主机上会更像这样: 物理主机上的 /dev/sda2 是对应着主机硬盘的分区,后面的数字表示分区号,数字前面的字母 a 表示…...

【Python】批量采集原神表情包~
嗨害大家好鸭~我是小熊猫(✿◡‿◡) 最近迷上了原神, 不自觉中就很喜欢保存广大旅行者制作的表情包~ 真的很有意思诶~ 源码资料电子书:点击此处跳转文末名片获取 一个个保存的话,好像效率很低嘛… 那我就发挥我小熊猫的老本行直接给把他们全部采集下…...

C语言基本语法注释类型关键字
C 基本语法 标识符 给变量所取的名字叫变量名,定义变量的名字需要遵循标识符的命名规则。 标识符是用来标识变量、符号常量、数组、函数、文件等名字的有效字符序列。 标识符的命名规则: 1.只能由字母、数字和下划线组成(例如:…...