Linux之进程

目录

一、冯诺依曼体系结构

二、进程

1、关于进程

关于PCB结构体

2、查看进程

①ps

 ②/proc

3、getpid

4、getppid

5、fork()

fork基本用法

6、进程状态

7、孤儿进程

8、进程优先级

修改nice值:top

9、进程的几个特性


一、冯诺依曼体系结构

冯诺依曼体系结构如下图所示:

而上面的输入设备,输出设备,存储器,运算器,控制器又是什么呢?

存储器:内存

输入设备:键盘,摄像头,话筒,磁盘,网卡...

输出设备:显示器,音响,磁盘,网卡...

CPU(中央处理器):包括运算器、控制器

运算器:算术运算,逻辑运算

控制器:CPU是可以响应外部事件的,协调外部就绪事件


首先说说运行速度:

CPU&&寄存器  >  内存 > 磁盘/SSD(固态硬盘) > 光盘 > 磁带

那既然CPU运行速度是最快的,为什么冯诺依曼体系结构中还要在输入输出设备中间用存储器呢,直接用CPU处理输入输出岂不是更好用,速度更快。

当然可以这样用,但是如果真的这样使用,就会造成昂贵的成本,原本几千快的电脑,如果全部使用CPU处理各种数据,可能会花费十几万甚至几十万的成本,这是十分不划算的,并且我们大众需要的是性价比高的,即价钱便宜性能好,所以这里引用了内存即存储器,速度比磁盘快,价钱也比CPU便宜,可以很好解决这方面问题。

存储器可以将数据缓存在存储器中,进而CPU在存储器中读取数据时,不用再访问外设,可以在一定程度上提高效率


CPU读取数据(数据+代码),都是从内存中读取的。站在数据角度上,CPU不和外设直接交互

CPU要处理数据,需要先将外设中的数据加载到内存。站在数据角度上,外设只和内存直接交互


有句话是:程序要运行,必须先被加载到内存中

现在我们可以用冯诺依曼体系结构知识解释,因为CPU读数据都是从内存中读取的,所以程序要运行,必须先被加载到内存中


下面举个例子,能更深入的理解冯诺依曼体系结构的知识:

小王和小张在两个不同的城市,他们用QQ联系,那么QQ发送一句话的过程大概是怎样的呢?

小王通过输入设备(键盘)将数据输入到存储器(内存)中,CPU通过内存分析数据后,再将数据写回给内存,之后内存再将数据给到输出设备(网卡),接着就发送到网络(后面会说到,这里只涉及冯诺依曼相关知识),然后到了小张那边用输入设备(网卡)接收消息,把数据从网卡读到内存里,继续刚刚的过程,将数据交给CPU计算分析,然后CPU再将数据写回内存,最后再将数据刷新到输出设备(显示器)

具体步骤如下图所示,紫色箭头就是上述全部过程:


二、进程

操作系统:先描述,再组织

1、关于进程

Windows下,我们自己电脑上启动一个软件,本质就是启动了一个进程

Linux下,运行一条命令,在运行的时候,其实就是在系统层面创建了一个进程

Linux是可以同时加载多个程序的,是可以同时存在大量的进程在系统中的(OS里就是内存中)


下面对进程下定义:

进程 = 对应的代码和数据 + 进程对应的PCB结构体

当把数据加载到内存中,就变为进程了,这时会生成一个struct结构体PCB,包含了该进程的所有属性,这时对进程的管理,就变为了对进程结构体PCB链表的增删查改


关于PCB结构体

PCB全称是:process control block,在不同的操作系统中,PCB的名字不同

在Linux中,PCB结构体是task_struct,它会被装载到内存中并且包含进程的属性信息


task_struct的内容:

①标识符:描述进程的唯一标识符,用来区分其他进程

②状态:任务状态,退出代码,退出信号等

③优先级:相对于其他进程的优先级

④程序计数器:程序中即将被执行的下一条指令的地址

⑤内存指针:包括程序代码和进程相关的数据的指针

⑥上下文数据:进程执行时处理器的寄存器中的数据

⑦IO状态信息⑧记账信息等等


2、查看进程

①ps

ps是查看进程的命令

首先打开两个页面,都是我自己路径下

在test.c文件里写了死循环打印hello world的程序,然后编译运行

在左边的页面内输入ps,ps只能查看当前终端的进程:

ps axj是查看所有的进程:

而我们要查看的是自己刚刚的进程,所以输入:ps axj | grep 'test'

再把头部带上,即输入:ps axj | head -1 && ps axj | grep 'test'

这样查看,我们可以发现,./test是在运行的,所以有./test进程,又因为grep在查看进程,所以还有一个grep进程

头部有一个PID,代表进程ID,它代表当前进程的ID值

这时我们将右边的死循环Ctrl + c终止了,这时再执行ps axj | head -1 && ps axj | grep 'test'命令,会发现只有一个grep进程了


 ②/proc

有一个系统文件夹是/proc,存放的是进程信息

这时我们运行./test,然后查看进程:

发现test的进程PID是21599,然后我们在proc这个系统文件夹中也可以看到当前的进程PID21599(-l是显示属性-d是只显示路径)

而当我们Ctrl + c终止死循环进程时,再查看就没有这个进程信息了

所以我们可以发现proc这个文件夹是动态的


3、getpid

getpid是获得我们的进程PID的,下面是用man查看getpid的介绍

需要包两个头文件,其中返回值pid_t其实就是无符号整型

接下来将test.c改造一下,使用getpid这个函数:

然后右边窗口运行test后,左边窗口查看进程:

可以发现getpid获得的PID和我们ps查看的PID相同

而我们如果想终止这个死循环,可以Ctrl + c终止,也可以kill -9 PID终止

Ctrl + c终止:

kill -9 PID终止:


4、getppid

getppid是获得父进程的PID

下面是通过man查看getppid

和getpid一样,同样是包含两个头文件,同样返回值是pid_t

接下来将test.c里改变一下,将ppid也打印出来:

通过观察得知:

运行出来的PID和PPID与我们grep查看的一样

我们终止后再重新运行,如下图:

却发现,PID变了,但是PPID却一直是21147,那我们用ps查看一下21147,如下图:

我们发现PID是21147的进程是bash,而前面我们说过,bash的shell外壳程序

所以在执行命令时,所有的命令最终都是以bash的子进程的方式去运行的


5、fork()

fork()是创建一个子进程

下面是man查看fork

fork在头文件unistd.h中

需要注意的是fork函数的返回值:

失败的时候:返回-1

成功的时候:①给父进程返回子进程的pid  ②给子进程返回0

下面使用fork给大家示范一下返回值的场景:

在fork函数前面打印一下进程的pid,然后执行fork函数后,分别打印fork函数的返回值ret,与对应的pid和ppid

大家观察可知,fork函数执行前,是父进程在执行,pid是22942,执行fork函数后,成功的话会有两个返回值①给父进程返回子进程的pid  ②给子进程返回0

所以ret是0的就是子进程,而子进程的pid是22943

ret是子进程pid(22943)的就是父进程,而父进程的pid和fork执行前的pid一样,都是22942

通过上面的示例,可以更清楚的理解fork的两个返回值


fork基本用法

fork之后代码是父子进程共享的

下面例子可以清楚显示:

在fork函数后,有if和else if语句,分别判断fork的两个返回值,且都是死循环,下面看结果:

一个父进程一个子进程,交叉进行死循环,让父子进程在fork函数后面执行不同的代码,所以fork之后有两个不同的执行流,可以有两个while(1)同时执行,而ret这个返回值,在父进程里面是子进程的pid,在子进程里面是0

并且可以清楚观察到,子进程的ppid就是父进程的pid


一个父进程可能有多个子进程,而一个子进程只能有一个父进程

所以父进程:子进程 = 1 :n

所以给父进程返回子进程的pid用于区分子进程,而子进程只有一个父进程,并不需要区分,所以返回0

而在创建一个子进程的时候,操作系统需要新建一个task_struct(PCB结构体),而这个新建的task_struct内部属性大部分是以父进程为模板的


fork函数实现时,运行到return前面就说明核心代码已经执行结束了

这时子进程已经被创建出来了,可能会已经被放到运行队列尾部了

所以这时父子进程一起执行,父进程被调度时会return,然后当子进程被调度时,return也会执行,所以fork函数会有两个返回值


6、进程状态

操作系统进程的状态:

新建:PCB资源刚分配好,还没有放到运行队列中就是新建状态

运行:task_struct 结构体在运行队列中排队,就叫做运行态

阻塞:等待非CPU资源就绪,这个状态就叫做阻塞状态

挂起:当内存不足的时候,OS通过适当的置换进程的代码和数据到磁盘,此时进程的状态就叫做挂起状态

退出:退出状态


Linux操作系统进程的状态:

R运行状态:表明进程要么在运行中,要么在运行队列里,对应上面的运行态

S睡眠状态:也可以称为可中断睡眠,表明进程在等待事件完成,对应上面的阻塞状态,

D磁盘睡眠状态:深度睡眠,不可以被中断,不可以被被动唤醒

t调试状态:调试时的状态

T暂停状态:单纯的暂停状态        

X终止状态:瞬时性非常强

Z僵尸状态:一个进程已经退出,还不允许被OS释放,处于一个被检测状态;维持该状态,是为了让父进程或OS来进行回收

只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程就进入僵尸状态

僵尸进程会造成资源泄露,必须使用wait/waitpid接口进行等待处理


7、孤儿进程

子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程称为“僵尸进程”

而如果父进程先退出,子进程还在运行,子进程就被称为“孤儿进程”

孤儿进程会被“领养”,被1号进程领养(init,即系统本身)

之所以要被领养,因为父进程退出后,未来子进程如果退出了,父进程早已不在,没有人来回收它,需要领养的进程进行回收

下面是test.c的代码,父进程执行三次就结束,而子进程一直死循环:

继续分为左右两个窗口,右边窗口运行,左边窗口观察进程:

可以观察到,右边开始运行以后,ps观察进程,蓝线划出来的就是子进程,这时父进程还没有退出,子进程的ppid还是父进程的pid,等父进程三次运行完退出后,子进程的ppid变为1,表示被1号进程领养


8、进程优先级

之所以要有优先级,是因为CPU是有限的,但是进程太多了,所以需要用这种方式竞争资源

优先级就是确定谁先获得资源,谁后获得资源

优先级是选择将谁放在CPU上执行的重要调度指标

Linux中具体的优先级做法:

优先级 = 老的优先级 + nice值  

下面具体演示:

创建两个窗口,右边窗口先写一个test.c,代码是死循环打印hello world,再加上打印pid的值,然后运行;在左边窗口观察进程信息,输入 ps -al | head -1 && ps -al | grep test:

在还没有运行程序时:

运行后:

可以看到进程信息中pid和打印的pid相同,所以就是正在运行的进程,并且蓝色圈圈出来的PRI就是优先级,NI就是nice值

PRI表示这个进程被执行的优先级,值越小越早被执行

NI是nice值,表示进程可被执行的优先级的修正数值

所以加入nice值后,新的优先级 = 老的优先级 + nice值,当nice值为负数时,该程序的优先级值会变小,优先级会变高,即越快被执行

修改nice值:top

首先重复刚刚的操作,可以看到当前是PRI是80,nice值是0

top相当于Windows中的任务管理器

再打开一个窗口,输入top

然后输入r

相当于告诉你renice就是修改nice值,而刚刚运行的pid是27103,所以再输入27103

现在就可以输入nice值,我们输入30,再用ps打印观察进程信息

可以发现优先级值变为了99,而nice值变为了19,那为什么不是30呢

因为Nice值的取值范围是-20 ~ 19,超过19自动当做19

所以Nice值为19,而优先级值也由刚刚的80变为了99

而我们如果想将优先级调高点,那就是nice值调低,将nice值输入-100,必须以sudo运行top:

这时nice值变为最小值-20,同时PRI也由80变为60,为什么不是刚刚的99-20变为79呢?其实每次设置优先级值都是由80开始设置,即从进程最开始的优先级开始设置


9、进程的几个特性

①竞争性:进程数量多,而CPU资源很少,所以进程直接是有竞争属性的,所以就有了优先级

②独立性:多进程运行,要独享各种资源,多进程运行期间互不干扰

③并行:多个进程在多个CPU下分别、同时进行运行,称之为并行

④并发:多个进程在一个CPU下采用进程切换的方式,在一段时间内,让多个进程都得以推进,称之为并发(里面有时间片、抢占与出让的概念)

时间片:每一个进程在CPU执行时都会有一段时间,比如10ms,运行完就该下一个进程进CPU

抢占与出让:有可能进程a在CPU中运行的时间是10ms,而5ms就进行完了,这时进程a就相当于在出让CPU资源;而抢占就是指优先级高的可以抢占优先级低的进程的CPU资源


切换:

CPU中有很多寄存器,如果此时进程a正在运行,那么CPU中的寄存器里面,保存的一定是进程a的临时数据,而寄存器中存储的进程a的临时数据,就叫做进程a的上下文数据

当进程a由于并发、时间片的约束,暂时被切下来时,需要进程a带走自己的上下文数据

带走进程a的上下文数据暂时保存的目的是:下次回CPU运行时,能够重新恢复上去,就能继续按照之前执行的逻辑继续向后执行,就如同之前没有中断过一样

CPU中的寄存器只有一份,但是上下文数据可以有多份,分别用于对应不同的进程


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

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

相关文章

2023年汉字小达人区级自由报名明天开赛,3个新问题和往年真题练一练

明天9月25日,备受关注的2023年第十届上海小学生汉字小达人区级自由报名的比赛就要开始了,最近还是有几个“小迷糊”家长刚听说这个活动,问了几个问题,我觉得挺有普遍性的,所以再次给大家回答一下,希望能够帮…

JavaWeb开发-07-MySQL(二)

一.数据库操作-DQL -- 准备测试数据 INSERT INTO tb_emp (id, username, password, name, gender, image, job, entrydate, create_time, update_time) VALUES (1, jinyong, 123456, 金庸, 1, 1.jpg, 4, 2000-01-01, 2022-10-27 16:35:33, 2022-10-27 16:35:35), (2, zhangwuji…

VUE使用DXFParser组件解析dxf文件生成图片

<template><div><input type"file" change"handleFileChange" /></div><el-table :data"tableData" style"width: 100%"><el-table-column prop"Control_No" label"序号" width…

Ubuntu 安装Nacos

1、官网下载最新版nacos https://github.com/alibaba/nacos/releases 本人环境JDK8&#xff0c;Maven3.6.3&#xff0c;启动Nacos2.2.1启动失败&#xff0c;故切换到2.1.0启动成功 2、放到服务器目录下&#xff0c;我的在/home/xxx/apps下 3、解压 $ tar -zxvf nacos-serve…

【计算机视觉】2.图像特征提取

图像特征提取 一、颜色特征量化颜色直方图聚类颜色直方图 二、边缘特征边缘边缘定义边缘提取边缘精细 三、特征点的特征描述子Harris角点FAST角点斑点SIFTHaar-like特征SURFORBLBPGabor 一、颜色特征 量化颜色直方图 HSV空间 优势&#xff1a;计算高效 劣势&#xff1a;量化问…

Linux基本操作符(1)

W...Y的主页 &#x1f60a; 代码仓库分享 &#x1f495; 目录 Linux的登录 Linux下基本指令 指令操作的理解 几个与用户操作符 ls 指令 pwd命令 cd 指令 touch指令 mkdir指令 rmdir指令 && rm 指令 什么叫操作系统&#xff0c;我相信如果是学计算机的都听说过&…

SpringBoot 学习(九)Redis

11. 集成 Redis 11.1 说明 SpringBoot 操作数据&#xff1a;sping-data、jpa、jdbc、mongodb、redis SpringBoot 2. 后&#xff0c;jedis 被替换为 lettuce jedis&#xff1a;采用直连&#xff0c;多线程操作不安全&#xff0c;增强安全性需使用 jedis pool 连接池&#xff0…

Java --- MySQL8之索引优化与查询优化

目录 一、索引失效场景 1.1、全值匹配 1.2、最佳左前缀规则 1.3、主键插入顺序 1.4、计算、函数、类型转换(自动或手动)导致索引失效 1.5、类型转换导致索引失效 1.6、范围条件右边的列索引失效 1.7、不等于(! 或者<>)索引失效 1.8、is null可以使用索引&…

asp.net企业生产管理系统VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio

一、源码特点 asp.net 企业生产管理系统 是一套完善的web设计管理系统&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为vs2010&#xff0c;数据库为sqlserver2008&#xff0c;使用c#语 言开发 二、功能介绍 (1)用户管理&…

Spring学习笔记11 GoF代理模式

Spring学习笔记10 JdbcTemplate_biubiubiu0706的博客-CSDN博客 新建个maven模块 static-proxy 演示静态代理 订单接口 测试 需求:统计每个业务方法的耗时 package com.example.proxy.service;/*** author hrui* date 2023/9/25 8:42*/ public class OrderServiceImpl implem…

分布式网络在移动医疗场景中的应用

随着医疗信息化建设实践的深入&#xff0c;越来越多的医疗机构开始借助网络信息技术改善其运营及管理模式&#xff0c;为患者提供更高质量、更高效率、更加安全体贴的医疗服务。移动医疗便是在此背景下产生的新业务需求。 常见的移动医疗场景 住院部&#xff1a;移动查房、智…

代码阅读分析神器-Scitools Understand

这里写目录标题 前言概要功能介绍1.代码统计2.图形化分析3.代码检查 使用方法下载及使用 前言 作为一名程序员&#xff0c;阅读代码是一个必须要拥有的能力&#xff0c;但无奈很多代码逻辑嵌套非常多&#xff0c;看起来非常吃力&#xff0c;看了那段逻辑就忘记了刚才的逻辑&am…

SpringBoot 集成 AKKA

文章目录 应用场景与 SpringBoot 集成示例 应用场景 AKKA 是一个用于构建高并发、分布式和容错应用程序的开源框架。它基于Actor模型&#xff0c;提供了强大的并发抽象和工具&#xff0c;适用于各种业务场景。以下是一些使用AKKA框架的常见业务场景的示例&#xff1a; 实时数据…

WordPress还原重置插件WP Reset 教程!

这是一篇完整的 WordPress 还原教程&#xff0c;我们将使用一款插件&#xff0c;快速重置整个 WordPress 网站。 有时在安装不同主题、网站插件后&#xff0c;可能会导致程序码彼此的冲突&#xff0c;而让网站出现跑版、错误等 ..&#xff0c;这时直接重新来过可能反而比较快一…

命令执行(rce)

1.命令与代码执行原理 命令执行原理 参数给变量未经过滤&#xff0c;直接使用了不安全的函数处理了变量 127.0.0.1&&ipconfig 有漏洞 常用的函数 assert,system,exec,shell_exec, eval,(反单引号&#xff09; 代码执行原理 参数给变量未经过滤&#xff…

56块钱搭建一个ubuntu 2204 linux 服务器

硬件pdd上淘的一个linux小盒子 应该是以前的机顶盒之类的 实物图如下 今天刚收到小盒子 找了个显示器 键盘 查到小盒子上通电 本来指示灯应该亮的 老板刷机之后 led灯都不亮了 不知道有没有开机 我还以为坏了 刚开始 然后直接连到显示器上 有输出 那说明没问题…

【C语言】进阶——结构体+枚举+联合

①前言&#xff1a; 在之前【C语言】初阶——结构体 &#xff0c;简单介绍了结构体。而C语言中结构体的内容还有更深层次的内容。 一.结构体 结构体(struct)是由一系列具有相同类型或不同类型的数据项构成的数据集合&#xff0c;这些数据项称为结构体的成员。 1.结构体的声明 …

Ubuntu 安装PostgreSQL

网上有各种版本的&#xff0c;也可以去官网看官方的文档。我是下载的PostgreSQL-11.4版本的。找到以后直接复制网上的压缩包链接就可以。 $ mkdir /opt/postgresql && cd /opt/postgresql $ wget https://ftp.postgresql.org/pub/source/v11.4/postgresql-11.4.tar.gz…

数据结构学习笔记——查找算法中的树形查找(平衡二叉树)

目录 一、平衡二叉树的定义二、平衡因子三、平衡二叉树的插入和构造&#xff08;一&#xff09;LL型旋转&#xff08;二&#xff09;LR型旋转&#xff08;三&#xff09;RR型旋转&#xff08;四&#xff09;RL型旋转 四、平衡二叉树的删除&#xff08;一&#xff09;叶子结点&a…

初学vue.js

准备Vue.js环境 ① 下载环境&#xff1a; javaScript语言的程序包&#xff1a;外部js文件 对于Vue来说&#xff0c;导入Vue的外部js文件就能够使用Vue框架了。 Vue框架的js文件获取: 官网提供的下载地址&#xff1a;https://cdn.jsdelivr.net/npm/vue/dist/vue.js ②导入环境…