preface
操作系统的四个特征:并发、共享、虚拟、异步。
目录结构
- 什么是进程
- 进程的组成
- 进程的生命周期
- 进程的组织方式
- 进程的同步以及通信方式
- 如何实现进程控制
一、什么是进程
进程是程序的一次执行过程,也可以是进程实体的一次执行过程。是操作系统分配资源的最小单位,程序是静态的,而进程是动态的。
进程的特征
-
结构特征 为使进程能独立运行,需要创建PCB(进程控制块),当然还需要操作系统分配了系统走远才能运行;由PCB、数据段、程序段构成了进程实体。一般说的创建进程,指的是创建进程实体中的PCB,撤销进程指的是撤销进程中的PCB。
-
动态性 进程的实质是进程实体或者说是程序的一次执行过程。由创建产生,调度执行,撤销而消亡,有生命周期。反观程序,只是一系列的静态指令集合。
-
并发性 在同一时刻,多个进程实体可能存在于内存,并且能并发运行。
-
独立性 进程是由操作系统独立分配资源的,可以单独运行。在早期,进程是操作系统调度的最小单位,现代操作系统,线程是操作系统调度最小单位。
二、进程的组成
1. PCB
1.1 进程标识符
用于唯一的表示一个进程,分为内部和外部。内部用于系统中调用,外部用于用户程序访问该进程时使用。
1.2 处理机状态(现场信息) 处理机状态信息主要是由处理机的各种寄存器中的内容组成的。处理机在运行时,许多信息都放在寄存器中。当处理机被中断时,所有这些信息都必须保存在 PCB 中,以便在该进程重新执行时,能从断点继续执行。这些寄存器包括:
- 通用寄存器,又称为用户可视寄存器,它们是用户程序可以访问的,用于暂存信息,在大多数处理机中,有 8~32 个通用寄存器,在 RISC 结构的计算机中可超过 100 个;
- 指令计数器,其中存放了要访问的下一条指令的地址;
- 程序状态字 PSW,其中含有状态信息,如条件码、执行方式、中断屏蔽标志等;
- 用户栈指针,指每个用户进程都有一个或若干个与之相关的系统栈,用于存放过程和系统调用参数及调用地址,栈指针指向该栈的栈顶。
1.3 进程调度信息
- 进程状态,指明进程的当前状态,作为进程调度和对换时的依据;
- 进程优先级,用于描述进程使用处理机的优先级别的一个整数,优先级高的进程应优先获得处理机;
- 进程调度所需的其它信息,它们与所采用的进程调度算法有关,比如,进程已等待 CPU 的时间总和、进程已执行的时间总和等;
- 事件,指进程由执行状态转变为阻塞状态所等待发生的事件,即阻塞原因。
1.4 进程控制信息
- 程序和数据的地址,指进程的程序和数据所在的内存或外存地(首)址,以便再调度到该进程执行时,能从 PCB 中找到其程序和数据;
- 进程同步和通信机制,指实现进程同步和进程通信时必需的机制,如消息队列指针、信号量等,它们可能全部或部分地放在 PCB 中;
- 资源清单,即一张列出了除 CPU 以外的、进程所需的全部资源及已经分配到该进程的资源的清单;
- 链接指针,它给出了本进程(PCB)所在队列中的下一个进程的 PCB 的首地址。
2. 数据段
3. 程序段
三、进程的生命周期
进程状态
总状态:创建、就绪、运行、阻塞、挂起(调用suspend原语,放到外存)、终止。
-
创建 为一个新进程创建 PCB,并填写必要的管理信息;其次,把该进程转入就绪状态并插入就绪队列之中。
-
静止就绪 由于刚创建时候的进程,不能获取到主内存资源,或者调用了suspend挂起原语,不会被cpu调度,切换到外存。进程状态为readys。
-
活动就绪 当系统的主内存能满足进程分配,或者直接调用了原语active,会从创建态->动态就绪,或者从静态就绪->动态就绪,但是此时还没有获得cpu资源。进程状态为readya。
-
运行 进程获取到cpu资源。
-
静态阻塞 当进程处于未被挂起的阻塞状态时,称它是处于活动阻塞状 态,表示为 Blockeda。当用 Suspend 原语将它挂 起后,进程便转变为静止阻塞状态,表示为Blockeds。处于该状态的进程在其所期待的事件 出现后,将从静止阻塞变为静止就绪。
-
活动阻塞 运行中的进程调用io操作,或者静态阻塞的进程调用active原语。
-
终止 进程的终止也要通过两个步骤:首先等待操作系统进行善后处理,然后将其 PCB 清零, 并将 PCB 空间返还系统。
四、进程的组织方式
一个系统中可能由成百上千个进程,需要有效的方式进行管理,然后由才做系统进行调度。
链接方式
根据PCB的状态,分成不同的队列,如就绪队列、阻塞队列、空闲队列,其中阻塞队列还可以根据不同阻塞原因分成不同阻塞队列(等待io、等待资源等)。就绪队列中,会按照优先级在队列中排好。
索引方式
根据不同进程状态,设置不同的索引表,并记录不同状态指针对应的索引表首地址,索引表的表目存储的是pcb在pcb表中对应的地址。
五、进程的通信以及同步方式
同步方式
信号量
1. 整型信号量
针对各进程共享一个临界资源的场景,相当于Java的semaphore,如果要获取的资源<0,则进程会进行忙等。
2. 记录型信号量
针对各进程共享一个临界资源的场景,相当于synchonized,如果要获取的资源<0, 会阻塞线程,不会进行忙等,等待在一个阻塞队列上。资源只能-1或者+1。
3. AND型信号量 AND 同步机制的基本思想是:将进程在整个运行过程中需要的所有资源,一次性全部地分配给进程,待进程使用完后再一起释放。只要尚有一个资源未能分配给进程,其它所有可能为之分配的资源也不分配给它。亦即,对若干个临界资源的分配,采取原子操作方式:要么把它所请求的资源全部分配到进程,要么一个也不分配。由死锁理论可知,这样就可避免上述死锁情况的发生。为此,在 wait 操作中,增加了一个“AND”条件,故称为AND 同步,或称为同时 wait 操作。
管程
用于简化同步操作,信号量需要成对的执行wait和signal方法。一个管程定义了一个数据结构和能为并发进程所执行(在该数据结构上)的一组操作,这组操作能同步进程和改变管程中的数据。
管程的特点
- 模块化。管程是一个基本程序单位,可以单独编译。
- 抽象数据类型。管程中不仅有数据,而且有对数据的操作。
- 信息掩蔽。管程中的数据结构只能被管程中的过程访问,这些过程也是在管程内部定义的,供管程外的进程调用,而管程中的数据结构以及过程(函数)的具体实现外部不可见。管程和进程不同,主要体现在以下几个方面: 虽然二者都定义了数据结构,但进程定义的是私有数据结构 PCB,管程定义的是公共数据结构,如消息队列等; 二者都存在对各自数据结构上的操作,但进程是由顺序程序执行有关的操作,而管程主要是进行同步操作和初始化操作; 设置进程的目的在于实现系统的并发性,而管程的设置则是解决共享资源的互斥使用问题; 进程通过调用管程中的过程对共享数据结构实行操作,该过程就如通常的子程序一样被调用,因而管程为被动工作方式,进程则为主动工作方式; 进程之间能并发执行,而管程则不能与其调用者并发; 进程具有动态性,由“创建”而诞生,由“撤销”而消亡,而管程则是操作系统中 的一个资源管理模块,供进程调用。
管程的同步使用wait/signal以及条件变量。
进程通信方式
管道
管道是半双工通信方式,如果需要全双工,需要两个管道。管道分为匿名管道和命名管道
1. 匿名管道
#include <unistd.h>
int pipe(int pipefd[2]);
调用pipe函数,会在内核中开辟出一块缓冲区用来进行进程间通信,这块缓冲区称为管道,它有一个读端和一个写端。pipe函数接受一个参数,是包含两个整数的数组,如果调用成功,会通过pipefd[2]传出给用户程序两个文件描述符,需要注意pipefd [0]指向管道的读端, pipefd [1]指向管道的写端,那么此时这个管道对于用户程序就是一个文件,可以通过read(pipefd [0]);或者write(pipefd [1])进行操作。pipe函数调用成功返回0,否则返回-1。
通信步骤:
(1)父进程创建管道,得到文件描述符指向管道的两端。
(2)fork出子进程,得到父进程获取到的文件描述符,指向同一个管道的两端。
(3)父进程关闭读端,子进程关闭写端。父进程向写段写数据,子进程向读端读数据。
特点:
- 单向通信,写->读
- 只能有血缘关系的进程进行通信
父进程把文件描述符传给子进程之后父子进程之间通信,也可以父进程fork两次,把文件描述符传给两个子进程,然后两个子进程之间通信, 总之需要通过fork传递文件描述符使两个进程都能访问同一管道,它们才能通信。
2. 命名管道FIFO
命名管道没有血缘关系进程的限制。FIFO不同于管道之处在于它提供一个路径名与之关联,以FIFO的文件形式存储于文件系统中。命名管道是一个设备文件,因此,即使进程与创建FIFO的进程不存在亲缘关系,只要可以访问该路径,就能够通过FIFO相互通信。值得注意的是, FIFO(first input first output)总是按照先进先出的原则工作,第一个被写入的数据将首先从管道中读出。
共享内存
共享内存是进程通信最快的方式,给多个进程开辟一个共同的内存。
(1)基于共享数据结构
(2)基于共享内存
消息队列
消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
信号
信号是事件发生时对进程的通知机制,有时也称为软件中断。
以下事件可引发内核为进程产生信号:
(1)硬件异常。
硬件检测到一个错误条件并通知内核,随机再由内核发送相应信号给相关进程。硬件异常的例子包括执行一条异常的机器语言指令。例如:被0除, 或者引用了无法访问的内存区域。
(2)用户键入了能够产生信号的终端特殊字符。其中包括中断字符(Ctrl+C)、暂停字符(Ctrl+Z)。
(3)发生了软件事件。例如,针对文件描述符的输出变为有效,调整了终端窗口大小,定时器到期,进程执行的CPU时间超限,或者该进程的某个子进程退出。
信号量
信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
socket
可以用于不同机器间的进程通信。
六、如何实现进程控制
进程控制主要通过操作系统原语,原语由一系列指令组合而成,是原子性执行的。
原语特征:
- 运行在核心态
- 执行期间不允许中断
- 运行时间较短,调用频繁
总结
进程是程序的一次执行,是动态的,他是系统分配资源的最小单位。