操作系统(4)进程

进程的定义
为了完成程序的并发执行,引入了进程、进程实体的概念。

系统为每个运行的程序配置一个数据结构,称为 进程控制块(PCB)
操作系统通过PCB来管理进程,因此PCB中应该包含操作系统对其进行管理的各种信息(如程序存放的位置)。

一个程序在运行的过程中会在内存中存在程序段(用来放置code)和数据段(用来放置程序运行的数据)。而吧PCB、程序段、数据段三部分放在一起就称为进程实体(进程映像),而创建进程,实质上就是创建进程实体中的PCB,而撤销进程,实质上就是撤销进程实体中的PCB。

注意:PCB是进程存在的唯一标志!
注意:PCB是进程存在的唯一标志!
注意:PCB是进程存在的唯一标志!

进程:是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位。

注:进程和进程实体是两种东西,进程实体是静态的,进程则是动态的。
在这里插入图片描述
注:寄存器的状态是指,在运行过程中进程会发生切换(并发),此时一个进程并没有执行完,就需要吧进程的当前运行情况记录下来保存在PCB当中。这样下一次切换回此进程的时候就能继续运行。

进程的组织

在现在的计算机当中,通常都有数十数百个进程,要把当前的进程组织起来才能方便管理。
在这里插入图片描述
进程的状态和其转换
在这里插入图片描述

进程是程序的一次执行,在执行的过程中,有时进程正在被CPU处理,有时有需要等待CPU的服务,可见进程的状态是会有很多种变化的。

三种基本状态

  • 运行态(Running):占用CPU,并在CPU上运行
  • 就绪态(Ready):已经具备运行条件,但是由于没有空闲的CPU,暂时不能运行
  • 阻塞态(Waiting/Blocked 又称:等待态):因为等待某一事件而不能运行

注:单核只能有一个进程在运行态,双核就可以有两个。

进程控制
简单理解控制就是实现上面的那些状态之间的转换。
之前我们有学到原语,即执行期间不允许中断,一气呵成的原子操作。其实现是采用了"关中断指令"和"开中断指令",在执行了关中断指令之后,外部中断会被屏蔽掉,而在执行开中断指令后才能正常接收外部中断。

因为进程状态的转换会把相同状态的进程放进一个队列当中,而且需要对PCB进行修改(修改进程标志位、将运行环境保存到PCB、从PCB恢复运行环境),这过程不能出现中断,所以需要原语来实现。

相关原语:

  • 进程的创建
  • 进程的终止
  • 进程的阻塞
  • 进程的唤醒
  • 进程的切换

注:阻塞和唤醒要成对出现

进程通信
在这里插入图片描述

进程是分配系统资源的单位(包括内存地址空间),因此各进程拥有的内存地址空间是相互独立的,并且两个进程之间是不能互相访问的,如果可以互相访问也就意味着一个进程可以随意修改另一个进程的数据,这是不被允许的,但是进程之间有时有时必须要交换信息的,比如你可以把游戏内容分享到你的朋友圈。为此操作系统提供一些方法来让进程之间进行信息传递。

1、共享存储
系统会为两个进程分配一个共享空间,两个进程可以通过这个共享空间进行互相访问,并且这种访问是互斥的,在进程一对共享空间进行操作的时候,只有等这个进程操作完,进程二才能对共享空间进行操作。
这种共享分为基于数据的共享是一种低级通信方式,比如只能在共享空间里面放一个长度为10的数组。
基于存储区的共享是一种高级通信方式,在内存中画一块共享存储区,数据形式、存放位置都由进程控制,而不是操作系统。

2、管道通信
"管道"是指用于连接读写进程的一个共享文件,又名pipe文件。其实就是在内存中开辟一个大小固定的缓冲区。
1、管道只能采用半双工通信,某一时间段内只能实现单向传输,如果要实现双向同时的通信,则需要设置两个管道。
2、管道的访问也是互斥的。这一点和共享存储是相同的。
3、数据是以字符流的形式写入管道,当管道写满时,写进程的write()系统调用会被阻塞,等待读进程将数据取走。当读进程将数据全部取走,管道变空,此时读进程的read()系统调用会被阻塞。
4、如果没写满,就不允许读没读空,就不允许写
5、数据一旦被读出,就从管道中被抛弃,这就意味着读进程最多只能有一个,否则可能会出现数据读错的情况。

3、消息传递
进程间的数据交换是以格式化的消息为单位,进程提供操作系统提供的"发送消息/接收消息"两个原语进行数据交换

一个格式化消息会分为:
消息头:包括发送进程ID、接收进程ID,消息类型、消息长度等格式化信息
消息体:消息本身。

消息传递:

  • 直接通信方式:消息直接挂到接收进程的消息缓冲队列上
  • 间接通信方式:消息需要先发送给之间实体(信箱)中,因此也称"信箱通信方式"

直接:每个进程都有一个消息缓冲队列,如果有另外一个进程想给该进程发送消息就会先创建一个格式化消息然后通过发送原语发送给目标进程,这个消息就会挂在目标进程的消息缓冲队列上,目标进程会通过接收原语依次接收消息并处理。 间接:系统会为各个进程管理一个信箱,这里包含了许多消息体,消息体中的消息头包含了由那个进程发送,那个进程接收,所以不用担心消息被取错。同样是采用发送和接收原语进行操作。