目录
进程是正在执行的程序,是大多数系统中的工作单元。进程需要一定的资源 (如CPU时间、内存、文件和 I/O设备) 来完成其任务。这些资源在创建进程或执行进程时被分配。
进程在运行时既可以包含一个线程,也可以包含多线程进程。
进程的概念
什么是进程?
- 进程是正在执行的程序,是大多数系统中的工作单元。
- 程序代码(文本段 | 代码段);
- 当前活动(程序计数器的值 和 处理器寄存器的内容);
- 堆栈段(临时数据、函数参数、返回地址、局部变量);
- 数据段(全局变量);
- 堆(进程运行期间动态分配的内存);
进程和程序的区别:
- 程序是驻留在某些存储中的被动实体; 如存储在磁盘上的文件内容( 常被称为可执行文件 )。而进程是一个活动的实体,它包含除程序之外的许多资源。
- 当一个可执行文件被装入内存时,一个程序才能成为进程。
许多进程可能运行相同的程序。但是:
- 它们被认为是独立的执行序列,尽管它们共享相同的程序代码; 但是数据段、堆、堆栈段却不同。 一个进程在执行时产生许多进程是很常见的。
进程的状态
当一个进程执行时,它会改变状态。进程的状态由其当前活动定义。
- 新的:正在创建进程
- 运行:正在执行指令
- 等待:进程正在等待某些事件的发生;(如等待 I/O读取)
- 就绪:进程正在等待分配给处理器;
- 终止:进程已经完成了它的执行。
进程状态图:
进程控制块
进程在操作系统中如何表示:
每个进程在操作系统中由一个进程控制块(PCB)表示。也称为任务控制块。它包含与特定进程有关的许多信息:
- 程序计数器: 计数器表示进程要执行的下个指令的地址。
- CPU 调度信息: 这类信息包括进程优先级、调度队列的指针和其他调度参数
要点:
- 系统利用PCB来控制和管理进程,所以PCB是系统感知进程存在的唯一标识
- 进程与PCB是一一对应的
- 通常进程队列是进程所对的PCB队列
- 操作系统通过PCB来感知进程的存在
进程调度
多道程序设计的目的是无论何时都有进程在运行,从而使CPU利用率达到最大化。
分时系统的目的是在进程之间快速切换CPU以便用户在程序运行时能与其进行交互。
为达到此目的,进程调度选择一个可用的进程到CPU上执行。单处理器系统从不会有超过一个进程在运行。如果有多个进程,那么余下的则需要等待CPU空闲并重新调度。
调度队列
当进程装载到系统中,就会被加到作业队列中。
作业队列:由系统中的所有进程组成;
就绪队列:由等待CPU执行的进程组成; 该队列通常用链表来实现。
队列图:是操作系统中流程调度的常见表示法
I/O设备队列:由等待特定I/O设备的进程组成的列表。每个设备都有自己的设备队列。
调度程序
调度程序的作用是: 以某种方式从调度队列中选择进程 来执行这些进程。
通常对于批处理系统,进程更多地是被提交,而不是马上执行。批处理系统的进程会被放到大容量存储设备(通常为磁盘)的缓冲地中,存储在那里以便以后执行。长期调度程序(long-termscheduler) 或作业调度程序 (job scheduler) :从该缓冲池中选择进程,并装入内存以准备执行。
短期调度程序 (short-term scheduler) 或 CPU 调度程序:从准备执行的进程中选择进程,并为之分配 CPU 。
这两个调度程序的主要差别是它们执行的频率。
- 短期调度程序必须频繁地为CPU 选择新 进程。
- 长期调度程序执行得并不频繁,在系统内新进程的创建之间可能有数分钟间隔
中期调度程序:能将进程从内存(或从CPU竞争)中移出,从而降低多道程序设计的程度,之后进程能被重新调入内存,并从中断处继续执行,称为交换(用于改善进程组合(比如所有进程以CPU为主或者I/O为主的,需要重新调度一下)或者因内存要求的改变引起了可用内存的过度使用而需要释放内存);
上下文切换
将CPU切换到另一个进程需要保存原来进程的状态并装入新进程的保存状态。这一任务称为上下文切换。进程关联是由进程的PCB来表示的。内核将旧进程的关联状态保存在其PCB中,然后装入经调度要执行的新进程的已保存的关联状态。
上下文切换是纯粹的开销。根据底层处理器的不同,它可能会消耗大量的CPU周期。
上下文切换已经成为性能瓶颈,程序员可以使用新的结构来尽可能地避免它。
进程操作
系统内的进程能并发执行,它们必须动态地被创建和删除。因此,操作系统必须提供某种机制(或工具)以创建和终止进程。
进程在其执行过程中,能通过系统调用创建多个新进程。创建进程称为父进程,而新进程称为子进程。这些新进程可以再创建其他进程,从而形成进程树。
大多数操作系统 (包括 UNIX 和 Windows 系列操作系统 )根据一个唯一的进程标识符( pid, 通常是个整数值)来识别进程。
通常,进程需要一定的资源 (如 CPU 时间、内存、文件、I/O 设备) 来完成其任务。在一个进程创建子进程时,子进程可能从操作系统那里直接获得资源,也可能只从其父进程那里获得资源。父进程可能必须在其子进程之间分配资源或共享资源(如内存或文件)。限制子进程只能使用父进程的资源能防止创建过多的进程带来的系统超载。
在子进程创建时,除了得到各种物理和逻辑资源外,它还能从父进程那里得到所需的初始化数据(或输入)。
当进程创建新进程时,有两种执行可能:
- 父进程与子进程并发执行
- 父进程等待,直到某个或全部子进程执行完毕
新进程的地址空间也有两种可能:
- 子进程是父进程的复制品
- 子进程装入另一个程序进来
进程终止
进程终止(只有被终止进程的父进程才能执行这一系统调用)
需要终止的原因:
- 子进程使用了超过它所分配到的一些资源;
- 分配给子进程的任务已经不再需要;
- 父进程退出(有些系统父进程终止其所有子进程都会终止,但有些系统如UNIX,如果父进程终止会将其所有子进程以init进程作为父进程,因此子进程仍然有一个父进程来手机状态和执行统计)如果父进程终止,那么操作系统不允许子进程继续。
进程间的通信
执行在操作系统内的并发进程可以是独立进程或协作进程。
- 如果一个进程不能影响或被其他进程所影响,那么该进程是独立地。显然,不与其他任何进程共享数据的进程是独立地。
- 如果一个进程能影响或被其他进程所影响,那么该进程是协作的。显然,与其他进程共享数据的进程是协作进程。
人们需要协作进程的理由:
- 信息共享:由于多个用户可能对同样的信息感兴趣,所以必须提供环境以允许对这些类型资源的并发访问
- 加快计算:如果希望一个特定任务快速运行,那么必须将它分成多个子任务,并行执行。
- 模块化:可能需要按模块化方式来构造系统。
- 方便:单个用户也可能同时执行多个任务。
协作进程的并发执行要求一定机制,以允许进程间相互通信和同步动作。
进程间通信有两种基本模式:
- 共享内存:允许以最快的速度进行方便的通信,在计算机中可以达到内存的速度,等等。
- 消息传递:对于交换较少数量的数据很有用,因为不需要避免冲突,对于计算机间的通信,消息传递也比共享内存更易于实现,等等。
共享内存系统:需要一个缓冲(无限缓冲|有限缓冲)来被生产者填充并被消费者所使用。
消息传递系统:需要缓冲(零容量缓冲,发送必须阻塞直到接收者接受信息;有限容量缓冲,如果消息队列未满,不阻塞,如果线路满,必须阻塞发送者知道队列中的空间可用为止;无限容量,从不阻塞发送者);
客户机-服务器系统通信
套接字可定义为通信的端点。一对通过网络通信的进程需要使用一对套接字,即每个进程各有一个。套接字由IP地址和端口号连接组成。套接字采用客户机-服务器结构。
使用套接字通信,虽然普遍和高效,但是它属于较为低层形式的分布式进程通信。只允许在通信线程之间交换无结构的字节流。