进程与线程基本概念

计算机中,CPU是最宝贵的资源,为了提高CPU的利用率,引入了多道程序设计的概念。当内存中多个程序存在时,如果不对人们熟悉的“程序”的概念加以扩充,就无法刻画多个程序共同运行时系统呈现出的特征。

 

一、进程的引入

多道程序系统中,程序具有:并行、制约以及动态的特征。程序概念便难以合适地反映系统中的情况:

1. 程序是一个静态的概念

程序是完成某个功能的指令集和。系统实际上是出于不断变化的状态中,程序不能反映这种动态性。

2. 程序概念不能反映系统中的并行特性

例如:两个C语言源程序由一个编译程序完成编译,若用程序概念理解,内存中只有一个编译程序运行(两个源程序看作编译程序的输入数据),但是这样无法说明白内存中运行着两个任务。程序的概念不能表示这种并行情况,反映不了他们活动的规律和状态变化。就像不能用菜谱(程序)代替炒菜(程序执行的过程)一样(这句话我稍微修改了一下,感觉应该是这样表诉才对)。

 

二、进程的定义

进程:一个具有一定独立功能的程序关于某个数据集合的一次运行活动,是系统进行资源分配和调度运行的基本单位

 

三、进程与程序的差别

1. 进程是一个动态的概念

进程是程序的一次执行过程,是动态概念。

程序是一组有序的指令集和,是静态概念。

2. 不同的进程可以执行同一个程序

区分进程的条件:所执行的程序和数据集合。

两个进程即使执行在相同的程序上,只要他们运行在不同的数据集合上,他们也是两个进程。例如:多个用户同时调用同一个编译程序编译他们编写的C语言源程序,由于编译程序运行在不同的数据集合(不同的C语言源程序)上,于是产生了一个个不同的进程。

3. 每个进程都有自己的生命周期

当操作系统要完成某个任务时,它会创建一个进程。当进程完成任务之后,系统就会撤销这个进程,收回它所占用的资源。从创建到撤销的时间段就是进程的生命期。

4. 进程之间存在并发性

在一个系统中,同时会存在多个进程。他们轮流占用CPU和各种资源。

5. 进程间会相互制约

进程是系统中资源分配和运行调度的单位,在对资源的共享和竞争中,必然相互制约,影响各自向前推进的速度。

6. 进程可以创建子进程,程序不能创建子程序

7. 从结构上讲,每个进程都由程序、数据和一个进程控制块(Process Control Block, PCB)组成

四、进程的重要特征

1. 动态特征:进程对应于程序的运行,动态产生、消亡,在其生命周期中进程也是动态的。

2. 并发特征:任何进程都可以同其他进程一起向前推进。

3. 独立特征:进程是相对完整的调度单位,可以获得CPU,参与并发执行。

4. 交往特征:一个进程在执行过程中可与其他进程产生直接或间接关系。

5. 异步特征:每个进程都以相对独立、不可预知的速度向前推进。

6. 结构特征:每个进程都有一个PCB作为他的数据结构。

进程最基本的特征是并发和共享特征。

五、进程的状态与转换

1. 进程的三种基本状态

a. 运行状态:获得CPU的进程处于此状态,对应的程序在CPU上运行着。

b. 阻塞状态:为了等待某个外部事件的发生(如等待I/O操作的完成,等待另一个进程发来消息),暂时无法运行。也成为等待状态。

c. 就绪状态:具备了一切运行需要的条件,由于其他进程占用CPU而暂时无法运行。

2. 进程状态转换

a. 运行状态 ===> 阻塞状态:例如正在运行的进程提出I/O请求,由运行状态转化为阻塞状态。

b. 阻塞状态 ===> 就绪状态:例如I/O操作完成之后,由阻塞状态转化为就绪状态。

c. 就绪状态 ===> 运行状态:例如就绪状态的进程被进程调度程序选中,分配到CPU中运行,由就绪状态转化为运行状态。

d. 运行状态 ===> 就绪状态:处于运行状态的进程的时间片用完,不得不让出CPU,由运行状态转化为就绪状态。

 

3.状态挂起 

挂起:在一个进程从内存转到外存

处在挂起状态的进程映像在磁盘上,目的是减少进程占用内存。

  • 等待挂起状态:进程在外存并等待某事件的出现
  • 就绪挂起状态:进程在外存,但只要进入内存,即可运行

4.与挂起相关的状态转换

a. 阻塞状态 ===> 阻塞挂起状态:没有进程处于就绪状态或就绪进程要求更多的内存资源。

b. 就绪状态 ===> 就绪挂起状态:当有高优先级阻塞进程和低优先级就绪进程。

c. 运行状态 ===> 就绪挂起状态:对抢先式分时系统,当有高优先级等待挂起进程因事件出现而进入就绪挂起。

d. 阻塞挂起状态 ===> 就绪挂起状态:当有阻塞挂起进程因相关事件出现。

 

5. 进程的类型

a. 系统进程:操作系统用来管理资源的进程,当系统进程处于运行态时,CPU处于管态,系统之间的关系由操作系统负责。

b. 用户进程:操作系统可以独立执行的的用户程序段,当用户进程处于运行态时,CPU处于目态,用户进程之间的关系由用户负责。

六、进程控制块

1. 进程的三个组成部分

a. 程序

b. 数据

c. 进程控制块(PCB):为了管理和控制进程,系统在创建每个进程时,都为其开辟一个专用的存储区,用以记录它在系统中的动态特性。系统根据存储区的信息对进程实施控制管理。进程任务完成后,系统收回该存储区,进程随之消亡,这一存储区就是进程控制块。

PCB随着进程的创建而建立,撤销而消亡。系统根据PCB感知一个进程的存在,PCB是进程存在的唯一物理标识(这一点可以类比作业控制块JCB)。

2. 进程控制块的内容

PCB在不同的语言中,可能用不同的数据结构表示。为了系统管理和控制进程方便,系统常常将所有进程的PCB存放在内存中系统表格区,并按照进程内部标号由小到大顺序存放。

整个系统中各进程的的PCB集合可用数组表示。这时进程内部标号可以与数组元素下标联系。

各系统预留的PCB空间往往是固定的,如UNIX系统中规定进程数量不超过50个。

操作系统不同,PCB的格式、大小及内容也不尽相同。一般的,应该包含如下四个信息。

a. 标识信息:进程名。

b. 说明信息:进程状态、程序存放位置。

c. 现场信息:通用寄存器内存、控制寄存器内存、断点地址。

d. 管理信息:进程优先数、队列指针。

 

七、进程控制块的组织

系统中,有着许多不同状态的进程,处于阻塞状态的进程阻塞原因各不相同,为了便于调度和管理,常将进程控制块PCB用适当的方法组织起来。

1. 线性结构

把所有不同状态的进程的PCB组织在一个表格中。

最简单,适用于进程数目不多的操作系统,如UNIX系统,缺点是调用时,往往需要查询整个PCB表,时间复杂度略高。

2. 索引结构

分别把具有不同状态的进程PCB组织在同一个表中,于是有就绪进程表、运行进程表(多机系统中,还有现在的多核系统应该也有吧)以及各种等待事件的阻塞进程表。

系统中的一些固定单元分别指出各表的起始地址。

3. 链式结构

采用队列形式时,每个进程的PCB中要增加一个链指针表项,指向队列的下一个PCB起始地址。

为了对这些队列进行管理,操作系统要做三件事:

a. 把处于同一状态的进程的PCB通过各自队列的指针链接在一起,形成队列。

b. 为每一个队列设立一个对头指针,总是指向队首的PCB。

c. 排在队尾的PCB的队列指针项内容应该是“-1”或者一个特殊符号,表示这是队尾PCB。

在单CPU系统中,任何时刻都只有一个处于运行态的进程

所有处于阻塞队列中的PCB应该根据产生阻塞的原因今进行排队,每一个都称为阻塞队列,比如等待磁盘I/O的阻塞队列,等待打印机输出的阻塞队列。

七、线程的基本概念
1.引入线程的目的

引入进程的目的是为了更好地使用多道程序并发执行,以提高资源利用率和系统吞吐量,增加并发程度;

而引入线程,则是为了减小程序在并发执行时所付出的时空开销,提高操作系统的并发性能。

2. 线程的定义

线程最直接的理解就是轻量级进程,它是基本的CPU执行单位,也是程序执行流的最小单元,由线程ID、程序计数器、寄存器集合和堆栈组成。线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可与同属一个进程的其他线程共享进程所拥有的全部资源。一个线程可以创建和撤销另一个线程,同一个进程中的多个线程之间可以并发执行。由于一个进程内部有多个线程,如果线程的切换发生在同一个进程内部,则只需要很少的时空开销。
3.线程与进程的关系

线程 = 进程 - 共享资源

4.线程与进程的比较

  • 进程是资源分配单位,线程是CPU调度单位。
  • 进程拥有一个完整的资源平台,而线程值独享指令流执行的必要资源,如寄存器和栈。
  • 进程具有就绪、阻塞和运行三种基本状态和状态间的转换关系。
  • 线程能减少并发执行的时间和空间开销
  1. 线程的创建时间比进程短。
  2. 线程的终止时间比进程短。
  3. 同一进程内的线程切换时间比进程短。
  4. 由于同一进程的各线程间共享内存和文件资源,可不通过进行直接通信。

一个进程应该包括:

  • 程序的代码
  • 程序处理的数据
  • 程序计数器中的值,指示下一条将运行的指令
  • 一组通用的寄存器的当前值,堆、栈
  • 一组系统资源(如打开的文件)

总之,进程包含了正在运行的一个程序的所有状态信息。

 

进程与程序的联系

  • 程序是产生进程的基础
  • 程序的每次运行构成不同的进程
  • 进程是程序功能的体现
  • 通过多次执行,一个程序徐可对应多个进程;通过调用关系,一个进程可包括多个程序。 

八、线程的三种实现方式

1. 用户线程:有一组用户级的线程库函数来完成线程的管理,包括线程的创建、终止、同步和调度等。

 

  •  用户线程的特征:
  1. 不依赖于操作系统的内核:内核不了解用户线程的存在
  2. 在用户空间实现的线程机制:每个进程有私有的线程控制块(TCB)列表,TCB由线程库函数维护
  3. 同一线程的用户线程切换速度快:无需用户态/核心太切换
  4. 允许每个进程拥有自己的线程调度算法
  • 用户线程的不足:
  1. 线程发起系统调用而阻塞时,则整个进程进入等待。
  2. 不支持基于线程的处理机抢占:除非当前运行线程主动放弃,它所在的进程的其他线程无法抢占CPU
  3. 只能按进程分配CPU时间:多个线程进程中,每个线程的时间片太少

2. 内核线程:由内核通过系统调用实现的线程机制,有内核完成线程的创建、终止和管理。

  •  内核线程的特征:
  1. 由内核维护PCB 和TCB
  2. 线程执行系统调用而被阻塞不影响其他线程
  3. 线程的创建、终止和切换相对较大:通过系统调用/内核函数,在内核实现
  4. 以线程为单位进行CPU时间分配:多线程的进程可获得更多CPU时间

3. 轻量级进程:内核支持的用户线程,一个进程可有一个或多个轻量级进程,每个轻量级进程有一个单独的内核线程来支持。

 4.用户线程与内核线程的对应关系

 

九、上下文切换

1.将cpu硬件状态从一个进程切换到另一个进程的过程称为上下文切换。

2.进程运行时,其硬件状态保存在cpu上的寄存器中 ,包括寄存器,程序计数器,程序状态寄存器,栈指针,通用寄存器,其他控制寄存器的值。

3.进程不运行时,这些寄存器的值保存在进程控制块PCB中,当操作系统要运行一个新的进程时,将PCB中的相关值送到对应的寄存器中

九、进程控制

1. 进程创建

  • Windows进程创建API:CreateProcess(filename)
  1. 创建时关闭所有在子进程里的文件描述符:CreateProcess(filename,CLOSE_FD)
  2. 创建时改变子进程的环境:CreateProcess(filename,CLOSE_FD, new_envp)
  •  Unix进程创建系统调用:fork / exec
  1. fork () 把一个子进程复制成两个进程:parent(old PID),child(new PID)
  2. exec () 用新程序来重写当前进程:PID没有改变

用fork和exec创建进程的示例

int pid = fork();              //创建子进程
if(pid = 0){                    //子进程在这里继续
// do anything(unmap memory,close net connections)
exec("program", argc, argv0, argv1);
}
  • fork () 创建一个继承的子进程
  1. 复制父进程的所有变量和内存
  2. 复制父进程的所有CPU寄存器(有一个寄存器例外)
  • fork () 的返回值
  1. 子进程的fork () 返回0
  2. 父进程的fork () 返回子进程标识符
  3. fork () 返回值可方便后续使用,子进程可使用getpid () 获取PID

 

 

 

原文地址:https://www.cnblogs.com/cjsword/p/12175113.html