先讲讲进程是什么。

首先,我们需要知道程序是什么。

程序就是一个指令序列。早期的计算机只支持单道程序。如下图

操作系统 进程是什么 进程的5种状态 进程的通信方式_进程通信

一个程序在内存中有数据段和程序段。程序的代码放在程序段内,程序运行过程的数据放在数据段内(如变量)。然后高地址存放数据段,地地址存放程序段。

后面发展到支持多道程序。即内存中同时放入多道程序,各个程序的代码,运行数据存放的位置不同。如下图:

操作系统 进程是什么 进程的5种状态 进程的通信方式_原语_02

所以就是系统系统为每个运行的程序排至一个数据结构,称为进程控制块(PCB,progress control block),就是一个程序对应一个PCB。里面有进程的状态,进程的寄存器,进程编号,内存界限,程序计数器等信息。

为了方便操作系统的管理,完成各程序并发执行,引入了进程,进程实体的概念。

PCB,程序段,数据段三部分构成了进程实体(又叫进程映像)

程序段:描述进程本身要完成的功能;

数据段:程序加工的对象和场所;

进程控制块:内存中存储,记录进程生存周期内状态变化的存储区域。不同操作系统有不同的进程控制块格式和信息,但基本包括进程标识符,当前状态,现场保护区,存储指针,占用资源表以及进程优先级等信息。它是进程存在的唯一标志。

一般而言,我们称进程实体为进程。

例如,我们说的创建进程就是创建进程实体里的PCB,而撤销进程也是撤销进程实体里面的PCB。

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

严格来说,进程并不等同于进程实体,进程实体是静态的,进程是动态的。

进程和程序的区别:

一般说进程是程序的一次运行过程,是动态地产生,变化和消亡。

进程的三种基本状态:

运行态:占有cpu,并且就在cpu上执行。

就绪态:已经具备运行条件,但由于没有空闲cpu,而暂时不能运行。(也就是cpu没有调度到它)

阻塞态:因等待某一事件而不能运行。

其实这个很好理解,如果看过我之前关于线程的讨论的话应该很容易理解。注意:单核处理机同一时间只有一个进程处于运行态,双核则是两个。

还有两个状态:

创建态:进程正在被创建,系统为其初始化PCB,分配资源。

终止态:进程正在从系统中撤销,回收进程的资源,撤销其PCB。

下面一张图可看出这五个状态的关系:

操作系统 进程是什么 进程的5种状态 进程的通信方式_操作系统_03

感觉和java的线程那里也差不多,理解起来很快。

这里简单说一下:就绪态通过进程调度可以变为运行态,运行态通过中断变为就绪态,运行态通过io请求等待事件进入阻塞态,阻塞态被唤醒,即等待事件结束,就变为了就绪态。

接下来我们讲进程的通信:

操作系统 进程是什么 进程的5种状态 进程的通信方式_原语_04

上面这张图大概目录了进程通信的全部东西,下面我们进行详细讲解。

下面的图片有助于理解,下面我们就跟着图片来讲解:

操作系统 进程是什么 进程的5种状态 进程的通信方式_操作系统_05

进程通信:就是指进程之间的信息交换。

各个进程拥有的内存地址空间相互独立,为了保证线程安全,操作系统中规定一个进程不能直接访问另一个进程的地址空间。比如上图中的进程一就不能直接访问进程二的地址空间。

但是进程之间又必须可以通信,比如微信发送图片时,就是微信这个进程和手机管理图片的进程间的通信,取出图片并且进行发送。

进程通信的方式主要分为三种:共享存储,消息传递,管道通信。

先来看第一种:共享存储。

操作系统 进程是什么 进程的5种状态 进程的通信方式_数据_06

共享存储就是操作系统另外分配一个内存区域用于进程间的通信,这就是共享空间,两个进程都可以访问这个共享空间,但是两个进程对共享空间的访问必须是互斥的,即同一时间段只能有一个进程访问这个空间,类似于线程那样。操作系统只负责提供共享空间和同步互斥工具(如P V操作,我看了一下,锁、PV操作、进程互斥与同步的实现 - qicheng777的博客​这个链接里讲了啥事pv操作,我总结了一下就是类似于一个AQS(不懂得同学自己建立模型理解,注意它的等待队列),然后为啥PV操作能实现进程互斥呢?可以看这位大哥的模型就很不错,一看就懂了,主要就是一个信号量,PV操作的加一减一,等待队列)。

然后共享存储又分为基于数据结构的共享和基于存储区的共享。

1.基于数据结构的共享:比如它的共享空间只能放一个长度为10的数组,数据量比较小,存储的数据形式也有限制。所以这种方式速度慢,限制多, 是一种低级通信‘

2.基于存储区的共享:此时操作系统只负责提供内存,然后由进程来控制数据的形式和存放位置。所以这种方式速度更快,是一种高级的共享方式。

然后来看第二种通信方式:管道通信。

操作系统 进程是什么 进程的5种状态 进程的通信方式_原语_07

管道:是指用于连接读写进程的一个共享文件,又名pipe文件。其实就是在内存中开辟一个大小固定的缓冲区。它的大小一般是和系统的内存页面大小一样,比如linux默认的内存页面大小是4kb,所以linux的管道大小也是4kb.

1.管道是才有半双工通信,有单片机基础或者计算机网络基础的同学都很容易理解这个概念,简单说就是同一时间只能实现单向传输,要实现双向同时通信,则需要两个管道。

2.各进程要互斥地访问管道。

3.数据以字符流的形式写入管道,当管道写满时,写进程的write()系统调用将被阻塞,等待进程将数据读走。当都进程将数据全部取走后,管道变空,此时读进程的read()系统调用将被阻塞。

4.如果没写满,就不会允许读。如果没读空,就不允许写。

5.数据一旦被读出,就会从管道中抛弃,这就意味着读进程最多只能有一个,否则可能会有读错数据的情况。

然后我们来看第三种进程通信方式:消息传递。

操作系统 进程是什么 进程的5种状态 进程的通信方式_原语_08

进程间的数据交换以格式化的消息为单位,进程通过操作系统提供的“发送消息/接收消息”两个原语进行数据交换。也就是说:一个进程调用“发送原语"这个api就可以把消息发送出去,通过”接收原语“就能取出消息。

一个消息包括消息头和消息体,消息头包括:发送进程的id,接收进程id,消息类型,消息长度等格式化的消息(计算机网络中发送的”报文“其实就是一种格式化的消息)。如果大家写过聊天室之类的小项目就很容易理解了,这就相当于自己自定义消息头,像tcp,udp的报头也是。而消息体就是消息内容了。

消息传递又包括两种通信方式:直接通信方式和间接通信方式。

1. 直接通信方式:消息直接挂到接收进程的消息缓冲队列上。也就是说,每个进程都有一个消息缓存队列。当进程A要给进程B通信,就先调用发送原语,把消息发送到进程B的消息缓存队列当中,然后进程B会调用接收原语,从自己的消息缓存队列当中取出消息。

2.间接通信方式:消息要先发送到中间实体(信箱)中,因此也称信箱通信方式,比如计算机网络中的电子邮箱系统。这就类似于,有一个中间部门专门管理这些信息,每个进程发送消息都是发送到这里,每个进程接收消息都是从这里取出。因为有消息头的目的进程id等信息,所以这一切都可以实现。

上面就是进程通信方式的讲解了。下面有个总结的图:

操作系统 进程是什么 进程的5种状态 进程的通信方式_数据_09