Linux 进程概念和状态

目录

一、冯诺依曼体系结构

二、操作系统

1.概念

2.理解操作系统的管理

硬件和管理

为什么要有操作系统

三、进程的概念

PCB:

进程的删除和子进程的创建

删除

创建子进程

四、进程的状态

七种状态:

实验查看部分状态:

R:

S:

D:

T/t:

Z/X:

运行状态

阻塞状态和阻塞挂起状态


一、冯诺依曼体系结构

我们在使用计算机本质上都是对数据进行处理,将数据输入到计算机,计算机在输出到一些设备上让我们看到。计算机在处理这些数据上都基本遵循着冯诺依曼体系。

输入设备:键盘、鼠标、磁盘、网卡、话筒...

存储器:内存

中央处理器:cpu

输出设备:显示器、声卡、磁盘、网卡...

这个过程就是对数据的流动加工,先将数据输入到输入设备中,输入设备再拷贝到存储器上,存储器将数据给运算器来进行基本运算处理数据,再把加工后的数据返给存储器,由存储器给输出设备。整个过程都是由控制器来控制的。我们都知道cpu是非常快的,但它容量很小,它也是计算机最重要的部分。

'

上图总结一下就是距离cpu越近,成本越高,容量越小。

存储器的作用:

体系中存储器起到的作用就像一个巨大的缓存。如果没有它,处理数据时就是外设(输入输出设备)把数据给cpu,但外设的速度又是特别慢的,cpu是很快的,这就导致数据的流动是一点一点流,cpu一点一点的处理数据,整体效率就很低。有了存储器,内存就会先将这些数据存起来,等达到一定要求时再给cpu让其运算,返给内存后,等到输出设备需要时再给它。这时的运算效率就成了内存到cpu,比外设到cpu快很多。

如果我们有钱也可以将内存和硬盘都换成cpu,不过那样的电脑就要几百万,所以内存和硬盘的存在也是计算机价格低的原因。

体会冯诺依曼体系的运行方式:

1.程序的运行

一个程序包含代码和数据,我们要通过代码运算数据就需要cpu来实现,这期间程序是一直在内存上的,我们使用输入设备将数据给内存上的程序在由cpu加工。这也像我们写代码一样,开辟的变量都是在内存上,最后通过内存由cpu去执行代码对数据进行加工得出结果,再由内存返给显示器让我们看到。

2.网上聊天

假如你和一个朋友在使用qq聊天,你给他发"在吗",可能为了保证数据的安全需要对数据加密,就要cpu的处理,从输入设备输入到内存,cpu在处理数据。使用qq需要网络,输出设备就必须能和网路建立联系,所以要将数据流到网卡上,中间还有网路的处理这里先不管。朋友的电脑就是从输入设备(网卡)上拿到加密的"在吗",将数据给内存,再到cpu解密返给内存,内存在给到输出设备(显示器)让朋友看到。

二、操作系统

1.概念

操作系统是一款软件,对软硬件资源管理的软件。在电脑开机时,等待一段时间显示器才会显示内容,这段时间就是在等待操作系统的启动。

广义认识:操作系统内核和操作系统外壳周边程序(对操作系统的使用方法)

狭义认识:操作系统内核。

2.理解操作系统的管理

操作系统结构示意图(层状结构):

硬件和管理

先来了解一下对硬件的管理,硬件都是有自己的属性,属性是用来描述硬件的状态及一些相关信息,就像写的通讯录存储人的信息,不过只会存储需要的信息,比如姓名、年龄、电话等等。

拿鼠标来举例,我们在更换鼠标的时,链接上新鼠标,右下角就会提示正在安装驱动程序,过一段时间新鼠标才可以使用。因为不同的鼠标都有不同的厂商,属性是略有不同。操作系统不可能有所有鼠标的属性数据,所以这些硬件的数据就要有厂商来提供接口,让操作系统拿到数据并可以修改数据。这些接口就是驱动程序,操作系统使用驱动管理来对接驱动程序对硬件进行管理

linux操作系统是使用c来写的,对硬件属性的描述,就可以使用struct来封装。硬件的属性有相同的地方,如厂商、电流大小等,不同的有状态以及功能,只用有相同处就可以使用数据结构进行管理,假如这里是用list对硬件进行链接,那我们对硬件进行管理就是对list进行增删查改。这种方式同样的适合其他的管理,例如文件管理,我们对目录下的增删查改。所以操作系统内是有着大量的数据结构进行管理工作的。

总结一下:管理某些东西我们要先描述他们的属性,在将它们放到一起组织起来(例如数据结构)。管理 == 先描述,再组织

为什么要有操作系统

再回到鼠标,我们现在准备完cs2,但感觉鼠标太快了,查看鼠标属性发现DPI是1200。现在要将DPI改成800,我们只需要将1200的选项改为800,操作系统就会对鼠标进行修改。这个过程中操作系统和鼠标的关系是管理者和被管理者,我们和操作系统的关系是甲方和乙方。我们作为甲方是不懂如何管理被管理者,所以需要一个人(操作系统)帮我们管理被管理者,我们就只需要拿到被管理者的属性,想修改才什么告诉乙方就行。

可是乙方也知道我们不懂管理,我们要是随便修改数据,乙方后面还怎么管理?数据已经乱了,此时乙方拿了份合同让我们签了,上面有对我们的限制,不让我们直接去操作系统修改数据,必须使用操作系统的调用接口才能让安排它做事。

这个系统调用接口就是操作系统给的一些函数,让我们使用函数来使用操作系统。这对于会c语言和了解系统的人还能使用,可那些不会的人就不能了,所以就有了用户部分。用户操作系统提供了shell外壳、lib(c/c++标准库)和部分指令,用户提供了指令操作mkdir、touch、ll等,还有我们熟悉的window的图形化界面。

总结一下:我们现在在来看操作系统,它在计算机中有着承上启下的作用,向下对软硬件资源进行管理(手段),向上为用户提供了一个良好(稳定的,安全的,高效的)的运行环境(目的)。

三、进程的概念

我们在使用window打开浏览器、微信等软件,其实就是在执行一个exe的可执行文件,执行文件时就会创建一个进程来控制程序的运行。

当我们结束到文件所对应的进程,执行的文件也将会不在执行。

在Linux中也是同理,当我们运行一个可执行程序,它就会生成进程。

ps -axj:查看进程

ps -ajx查看的进程过多,可以使用 | grep [文件] 搭配查看。

上面可以看到./test.exe确实在进程里,下面的test.exe是grap的进程,之前说过指令本身也是可执行文件,只要是可执行文件在执行时都会有进程。

刚刚也看到了进程是可以同时存在多个的,操作系统自然要对进程进行管理(先描述,再组织),那是在什么时候创建的进程呢?

PCB:

进程信息被放在一个叫做进程控制块的数据结构中,可以理解为进程属性的集合, 这个集合就是PCB。课本上称之为PCB(process control block)。在Linux中PCB被称为**tesk_struct,**它会被装载到RAM(内存)里并且包含着进程的信息.

我们上面已近了解了冯诺依曼体系,根据这个体系,要想运行程序,就要先将程序的数据和代码加载到内存当中再由,内存交给cpu让其计算。进程显然就是对这些程序的数据和代码进行处理,在它们加载到内存后,操作系统就要对它们进行管理,为每个程序创建一个PCB的结构体来描述,里面放着程序的所有属性,指向对应的代码和数据的指针,以及存放下一个进行的指针(假如用list来组织)。这时想让cpu运算哪个程序将它的PCB给cpu就可以了。

操作系统也是一款软件,它也要遵循冯诺一曼体系,电脑启动时就会加载到内存中,不过它是没有进程的。

总结一下:进程 == PCB+自己的代码和数据。Linux下就是tesk_struct+自己的代码和数据。

test_struct内容分类:

  • 标示符: 描述本进程的唯一标示符,用来区别其他进程。
  • 状态: 任务状态,退出代码,退出信号等。
  • 优先级: 相对于其他进程的优先级。
  • 程序计数器: 程序中即将被执行的下一条指令的地址。
  • 内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针
  • 上下文数据: 进程执行时处理器的寄存器中的数据[休学例子,要加图CPU,寄存器]。
  • I/ O状态信息: 包括显示的I/O请求,分配给进程的I/ O设备和被进程使用的文件列表。
  • 记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。
  • 其他信息

进程的删除和子进程的创建

删除

写一个死循环

Ctrl+c:在用户层面终止程序

kill -9 [pid]

**pid就是标识符,是tesk_struct的一员用来描述本进程的唯一标示符,区别其他进程。**在ps -ajx下可以看到。

运行程序,查看他的pid,ppid是他的父进程,每个进程都是由他的父进程创建的。

kill -9 22358,删除进程。

创建子进程

fork:创建一个子进程,当前程序是子进程就返回0,是父进程就返回子进程的pid.

getpid:查看当前进程的pid

getppid:查看当前进程的父进程pid

代码:

执行结果:

这个fork创建子进程会继承父进程从fork开始下面的所有代码,从上面的代码就可以看出,因为id值的不一样父子进程分别执行了不同结果的数据。

总结一下:fork创建的子进程是有自己的tesk_struct的(他有自己的pid),代码上是继承父进程fork以下包括fork那行的所有代码,数据上因为fork的返回值不同所以和父进程输出的结果是不一样的。

四、进程的状态

七种状态:

  • R:运行状态
  • S:浅度睡眠状态
  • D:深度睡眠状态
  • T/t:暂停状态
  • Z:退出状态
  • X:死亡状态

实验查看部分状态:

R:

代码:

查看运行test.c时进程的信息:

复制代码
 while :; do ps ajx | head -1 && ps ajx | grep test.exe | grep -v grep; sleep 1; done

命令行执行上面的命令可以循环查看程序的进程,这里查看的是test.exe,修改test.exe就可以查看其他程序进程。

运行进程后cpu执行代码,它进入循环后一直在执行while,进程的PCB一直在cpu的队列中(每个cpu都有一个自己的队列,来让进程轮流调用cpu),这时这个进程就是R状态。+代表是前台运行,没有则是后台。

S:

代码:

运行时进程的信息:

这段代码使用了printf,cpu在执行printf时需要调用显示器的资源,进程在等待外设资源就绪时就是S状态。显示器是外设,外设的速度是比cpu慢许多的,所以在这进程运行的大部分时间都是在调用显示器资源,R状态只会停留很短的时间。

D:

D状态的场景是很难造的,这里就简单说明一下。

场景:一个进程在给磁盘写入1G的数据,这时操作系统发现内存严重不足,Linux操作系统有权杀掉进程来释放空间,它就将这个正在等待磁盘写入数据的进程杀掉了。磁盘写着写着数据发现进程没了,磁盘就不知道要怎么处理这些数据,可其他进程也要调用磁盘,磁盘就不会处理这些未写完的数据,这就造成了数据的丢失还暂用了空间。

操作系统为了解决这个问题就创建了D状态(深度睡眠,不可被系统杀掉),解除D状态只能等进程自己醒来(数据传完)或重启/断电。

T/t:

让进程暂停需要kill命令,kill是一个向进程发送信号的命令。

kill -l:查看所有信号

kill -19:暂停进程

kill -18:解除暂停

解除暂停后进程会成为后台进程,只能kill -9杀掉进程,Ctrl+c无法杀掉。

Z/X:

代码:

运行后杀掉子进程:

杀掉子进程发现子进程依旧存在,进入了Z状态。进程在被杀掉后会先清楚掉程序在内存中的代码和数据,test_struct不会被删除,它会生成退出信息等待父进程来读取,读取后再进入X状态清楚这个程序的test_struct。这个过程就像你让一个朋友帮你做了件事,他在做完后会告知你一声这件事完成的状态。

上图,杀掉子进程后,因为父进程在运行没有去读取子进程的退出信息,子进程就成了Z状态,这个进程也被称为僵尸进程。

僵尸进程的危害:当父进程死亡后,子进程变为僵尸进程就可能会一直存在,导致内存泄漏,因为没有父进程读取它。OS(操作系统)为了解决这个问题,就将没有父进程的子进程(也称孤儿进程)让1号进程(OS本身)领养。

在操作系统内部还细分了很多种状态:

这里只介绍运行、阻塞和阻塞挂起状态。

运行状态

运行状态就是R,只要进程进入cpu的队列中就是运行状态。上面查看S状态使用了while写了死循环,但cpu在跑进程时不可能因为遇到死循环就只跑这一个进程,所以这里的问题就是cpu是如何进行多个进程的同时调用?

时间片:进程的PCB内都有自己的调度信息,里面有个时间片,cpu会根据时间片让进程使用多长时间,时间到了重新进入queue排队。

但进程重新进入queue去调用cpu不可能让cpu从头再开始运行代码。这时就需要寄存器了,每个cpu内都有寄存器,用来存储进程调用cpu的状态,进程需要重新进入queue时,会保留上一次进入cpu结束时寄存器的内容,也就达到再次使用CPU可以延续上次使用状态的效果。(这是OS教材调度算法的一种,Linux不是这样调度的)。

CPU寄存器的信息也程为上下文数据,在进程的切换时最重要的就是保护上下文数据。要注意的是寄存器 != 寄存器内容,寄存器是硬件,寄存器内容是数据。

阻塞状态和阻塞挂起状态

阻塞:S和D状态都是等待外设的资源就绪,外设内也有自己的queue来让进程调用,进程等待外设就会将自己的task_struct放到外设的queue内,这时进程就是阻塞状态,调用完后外设再回到cpu的queue内变成运行状态。

挂起:磁盘在内有一块swap分区,当内存特别吃紧时,有的进程是阻塞状态,OS就会将这个进程的代码和数据放到分区中,结束阻塞状态时会将数据和代码拿回内存。代码和数据在分区时就是挂起状态,不过挂起通常是伴随阻塞状态一起的,被称为阻塞挂起状态。

相关推荐
川贝枇杷膏cbppg6 分钟前
DmServiceDMSERVER.log是干嘛的
java·服务器·数据库
fufu03116 分钟前
Linux环境下的C语言编程(四十二)
linux·c语言·算法
Trouvaille ~9 分钟前
【Linux】进程调度与环境变量:Linux内核的智慧
linux·运维·服务器·操作系统·进程·环境变量·调度算法
HalvmånEver10 分钟前
Linux : 基础IO(三)
linux·运维·算法
oushaojun212 分钟前
linux中backtrace实战
linux·运维·算法·backtrace
soft200152516 分钟前
MySQL 8.0.39 Rocky Linux 一键安装脚本(完整可直接运行)
linux·mysql·adb
Nerd Nirvana18 分钟前
WSL——Windows Subsystem for Linux流程一览
linux·运维·服务器·windows·嵌入式·wsl·wsl2
CS创新实验室1 小时前
计算机考研408【操作系统】核心知识点总结
java·linux·考研·计算机·操作系统·408
bulucc1 小时前
vim 快捷操作
linux·编辑器·vim
CAFEBABE 341 小时前
安装完docker之后怎么使用
运维·docker·容器