进程基础知识

进程与程序的区别

程序:静态的,就是存放在磁盘里的可执行文件,就是一系列的指令集合。

进程:是动态的,是程序的一次执行过程;同一程序多次执行会对应多个进程;比如你使用QQ同时登陆多个账号,每一个账号就是一个进程。

如何进行区分这些进程呢?

当进程被创建时,操作系统会为该进程分配唯一的、不重复的进程ID号。(PID)

操作系统记录信息:

记录PID、进程所属用户(UID),可以让操作系统区分各个进程;

记录给进程分配了哪些资源(如:分配多少内存、正在使用哪些I\O设备、正在使用哪些文件),可用于实现操作系统对资源的管理;

记录进程的运行情况(如:CPU使用时间、磁盘使用情况、网络流量情况等),可用于实现操作系统对线程的控制、调度

这这些信息全部被放在一个数据结构PCB中,即进程控制块;操作系统需要对各个并发运行的进程进行管理,但凡管理时所需要的信息,都会放在PCB中

进程当前的状态:就绪态、阻塞态、运行态

进程的组成

PCB:进程描述信息;进程控制与管理信息;资源分配清单;处理机相关信息

程序段:程序的代码(指令序列)

数据段:运行过程中产生的各种数据(如:程序中定义的变量)

注意:其中PCB是给操作系统用的;程序段、数据段是给进程自己用的。

一个程序是如何运行的?

程序运行过程

进程就是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位(其中进程实体就是程序在运行过程中,某一状态的改变,比如上述:x++;x=2)。

一个进程被调度,就是指操作系统决定让这个进程上CPU运行。

注意:同时挂起三个QQ号,会对应三个QQ进程进程,他们的PCB、数据段各不相同(不同的用户信息等),但是程序段内容都是相同的(都是运行着相同的QQ程序)。 

进程相比于程序的特性:

动态性:进程最基本的特性;进程是程序的一次执行过程,是动态地产生、变化和消亡;

并发性:内存中有多个进程实体,各进程可并发执行;

独立性:进程是能独立运行、独立获得资源、独立接受调度的基本单位;

异步性:各进程按各自独立的、不可预知的速度向前推进,操作系统要提供“进程同步机制”来解决异步问题(注意:异步性会导致并发程序执行结果的不确定性)

结构性:每个进程都会配置一个PCB。结构上,进程是由程序段、数据段、PCB组成的。

进程的状态和转换:

进程状态

 系统中可能会有很多个进程处于就绪态;当CPU空闲的时候,操作系统就会选择一个就绪进程,让他上CPU运行;

如果一个进程此时在CPU上运行,此进程处于“运行态”,CPU会执行该进程对应的程序(执行指令程序);

在进程运行过程中,可能会请求等待某个事件的发生(如等待某种系统资源的分配,或者等待其它进程的响应)。在这个事件发生之前,进程无法继续进行往下执行,此时操作系统会让这个进程下CPU(不可能一直让他占有CPU资源),并让他进入“阻塞态”;

当CPU空闲时,又会选择另一个“就绪态”进程上CPU运行;

一个进程可以执行exit系统调用,请求操作系统终止该进程。此时该进程会进入“终止态”,操作系统会让该进程下CPU,并回收内存空间资源,最后还要回收该进程的PCB;

终止完成后,进程结束。

进程状态转换

进程状态

运行态->阻塞态是一种进程自身做出的主动行为;

阻塞态->就绪态不是进程自身能控制的,是一种被动行为。

注意: 不能由阻塞态直接转换为运行态,也不能由就绪态直接转换为阻塞态(因为进入阻塞态是进程主动请求的,必然需要进程在运行时才能发出这种请求)

其中运行态装换为就绪态:

时间片到:CPU收到一个时钟中断的信号,发现该进程已经运行很长一段时间了,不应该让其再运行了,这时就要被剥夺CPU资源。

基本状态:就绪、运行、阻塞

单CPU情况下,同一时刻一个进程处于运行态;多CPU多个。

进程PCB中,会有一个变量state来表示进程的当前状态。

如何实现进程控制

进程控制需要一气呵成,假设PCB中的变量state表示进程当前所处的状态,1表示就绪态,2表示诸阻塞态

state存放

假设进程2等待的某个事件已经发生了,那么控制进程的内核程序主要做两件事:

1.将PCB2的state置为1;

2.将PCB2从阻塞队列放到就绪队列中。

注意:如果在完成第一步之后,收到了中断信号,那么此时PCB2任然在阻塞队列中,但是其state=1,导致操作系统某些关键数据结构不统一的情况;所以转换要“一气呵成”。

“原语”的执行具有原子性,即执行过程只能一气呵成,期间不允许被中断;可以使用“关中断指令”和“开中断”指令这两个特权指令实现原子性;CPU执行力关中断指令之后,就不再检查中断信号,直到执行开中断指令之后才会恢复。这样,关中断、开中断之间的这些指令就是不可被中断的。

进程的创建

创建原语:申请空白PCB;为新进程分配所需资源;初始化PCB(PID,UID);将PCB插入就绪队列(创建态->就绪态)

引起进程创建的事件:

1.用户登录:分时系统中,用户登录成功,系统会建立为其建立一个新进程(比如:QQ登录)

2.作业调度:多道批处理系统中,有新作业放入内存中,会为其建立;(就是从外存中挑选一个程序放入到CPU中,使其运行)

3.提供服务:用户向操作系统提出某些请求;

4.应用请求:由用户主动请求创建一个子进程。

进程终止

撤销原语:从PCB集合中找到终止进程的PCB;若进程正在运行,立即剥夺CPU,将CPU分配给其它进程;终止其所有子进程;将该进程拥有的所有资源归还给父进程或操作系统,删除PCB

引起进程终止的事件:

1.正常结束(exit系统调用);

2.异常结束:整数除以0;非法使用特权指令,然后被操作系统强行杀掉

3.外界干预:用户选择执行一个指令杀掉进程

进程的阻塞和唤醒

进程阻塞

阻塞原语:找到阻塞进程对应的PCB;保护进程运行现场,将PCB状态信息设置为“阻塞态”,暂时停止进程运行;将PCB插入相应事件的等待队列(运行态->阻塞态)

引起进程阻塞的事件:需要等待系统分配某种资源;需要等待相互合作的其它进程完成工作

进程唤醒

唤醒原语:在事件等待队列中找到PCB;将PCB从等待队列移除,设置进程为就绪态;将PCB插入到就绪队列,等待被调度

引起进程唤醒的事件:等待事件发生(因何阻塞,因何唤醒)(阻塞->就绪)

进程的切换(运行->就绪,就绪->运行)

切换原语:将运行环境信息存入PCB;PCB移入相应队列;选择另一个进程执行,并更新其PCB;根据PCB恢复新进程所需的运行环境

引起进程切换的事件:

1.当前进程时间片刻(就是进程运行时间太长了)

2.有更高优先级的进程到达

3.当前进程主动阻塞

4.当前进程终止

注意:其中的运行环境信息

CPU中会设置很多“寄存器”,用来存放程序运行过程中所需要的某些数据。

PSW:程序状态字寄存器(进程是就绪态、运行态...)

PC:程序计数器,存放下一条指令的地址

IR:指令寄存器,存放当前正在执行的指令

通用寄存器:其它一些必要的信息

这里注意另一个进程在运行过程中,也需要使用各种寄存器,那么前一个进程的信息就直接丢失了吗?

不会,在进程切换时先在PCB中保存这个进程的运行环境(保存一些必要的寄存器信息,比如:PSW,PC,通用寄存器);当原来的进程再次投入运行时,通过PCB恢复之前的运行环境

无论时哪个进程控制原语,要做的无非三类事情

1.更新PCB中的信息(修改进程状态,保存\恢复运行环境);

2.将PCB插入合适的队列;

3.分配/回收资源

进程间通信

进程间通信是指两个进程之间产生数据交互

进程是分配系统资源的单位(包括内存地址空间),因此各进程拥有的内存地址空间相互独立。(一个进程不能访问其它进程的内存地址空间,比如:你下载一个APP,如果他可以访问你的微信,直接将你的私密信息拿走了)

所以,进程间不能直接进行相互访问,要通过操作系统

共享内存

一个进程申请一块共享内存,其它进程也可以进行访问;但是注意各个进程对共享内存的访问应该是互斥的(一个进程在访问时,其它进程应该等待)

基于数据共享:比如共享空间里只能放一个长度为10的数组。速度慢、限制多,低级通信。

基于存储区共享:操作系统在内存中划出一块内存共享区,数据形式、存放位置由通信进程决定。速度快。

消息队列(传递)

进程间的数据交换以格式化的消息为单位。进程通过操作系统提供的“发送消息\接受消息”两个原语进行数据交换。

消息头(发送进程ID、接受进程ID、消息长度等格式化信息)+消息体(一个进程传输给另一个进程的数据)

直接通信方式

消息发送进程要指明接收进程的ID

操作系统的内核中,管理着各个进程的PCB;在各个进程PCB中包含着一个消息队列;其它进程要给该进程发送消息,要被该进程接收的消息,都是存放在该进程的消息队列中

比如:如果进程P,要给Q发送消息,使用原语(send(Q,msg)),先给操作系统,操作系统再将msg放在Q的PCB消息队列中;在接收到消息之后,进程Q会使用接收原语receive(p,&msg),操作系统会从进程Q的消息队列中找到消息msg,将msg复制到进程Q的地址空间中。

直接通信

间接通信方式

通过“信箱”间接地通信。

比如:进程P要与进程Q进行通信,进程P先向操作系统申请一个邮箱或者多个邮箱,进程P使用原语send(A,msg),进程Q使用原语receive(A,&msg)从信箱A中接收这个消息;可以多个进程同时向一个信箱发送消息,也可以多个同个进程同时从一个邮箱接收消息。

间接通信

 管道通信

可以将其就想象成我们平时看到的“水管”,水管的水流只能由一边到另一边,不能是双向,那么管道之间的数据传输也就是单向传递的

“管道”是一个特殊的共享文件。其实就是在内存中开辟一个大小固定的内存缓冲区(进程就可以向该管道中写数据和读数据);具有先进先出的特性(可以理解为循环队列)

注意管道与共享内存的区别:
管道的数据具有先进先出的特性,先写入的数据,其它进程如果要读数据,只能将先写入的数据拿走;而共享内存就是可以从任意位置读取数据

总结:

1.管道只能采用半双工通信,某一段时间内只能实现单向传输。要实现双向,设置两个管道;

2.各个进程要互斥访问管道(操作系统实现);

3.当管道写满时,写进程将阻塞,直到读进程将管道中数据取走,即可唤醒写进程;

4.当管道读空时,读进程将阻塞,直到写进程往管道中写入数据,即可唤醒写进程;

5.管道中的数据一旦被读出,就彻底消失。因此,多个进程读同一管道时,可能错乱。解决方案:允许多个写进程,多个读进程,但系统会让各个读进程轮流从管道中读数据。(Linux)

注意:只要管道没满或者没空;进程就能向管道写或读数据。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值