操作系统——进程和线程相关知识


前言

本文的主要内容是进程和线程相关知识,包括进程的定义、组成、组织方式和特征,进程的状态与转换,进程控制与进程通信,以及线程的概念和多线程模型,重点掌握进程的一些基本知识,原语的应用以及线程和进程之间的异同。


一、进程的基本知识

1、进程的定义

程序就是一个指令序列,早期的计算机只支持单道程序。
单道程序下的程序代码存放在程序段内,程序运行过程中处理的数据存放在数据段内(比如变量)。
引入多道程序技术之后,内存中同时存放多道程序,各个程序的程序代码和数据存放的位置不同,为了方便操作系统的管理,完成各程序并发执行,引入了进程、进程实体的概念。
系统为每个运行的程序配置一个数据结构,它称为进程控制块(PCB, Procedure Control Block),用来描述进程的各种信息,比如程序代码的存放位置和数据的存放位置。
进程控制块(PCB)、程序段和数据段就构成了进程实体,进程实体也称为进程映像。
一般情况下,进程实体简称为进程,所谓创建进程,实质上就是创建进程实体中的PCB,而撤销进程,实质上就是撤销进程实体中的PCB。
PCB是进程存在的唯一标志!
进程从不同的角度有多种定义,不管是哪种定义,其都强调动态性,比较传统的定义有:
①进程是程序的一次执行过程。
②进程是一个程序及其数据在处理机上顺序执行时所发生的活动。
③进程是具有独立功能的程序在数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位。
引入进程实体后,进程还可定义为:进程是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位。
严格来说,进程和进程实体并不一样,进程实体是静态的,进程则是动态的。但除非特别强调两者的区别,一般认为进程实体就是进程,所以也可以说:进程由程序段、数据段和PCB组成。

2、进程的组成

上面已经提到过,进程由程序段、数据段和PCB组成。其中程序段存放程序代码;数据段存放程序运行时使用、产生的运算数据,如全局变量、局部变量、宏定义中的常量;操作系统通过PCB来管理进程,因此PCB中应该包含操作系统对其进行管理所需的各种信息。
PCB中所包含的信息如下图所示。
请添加图片描述

3、进程的组织方式

在一个系统中,通常有成百上千个PCB,为了有效管理这些PCB,应当采取适当的方式对它们进行组织。
进程的组织方式包括链接方式和索引方式。
在这里插入图片描述
链接方式主要利用的是一系列指针分别指向不同的状态,这些状态有:执行态、就绪态和阻塞态,具体的内容如下图所示。
请添加图片描述
索引方式和链接方式比较类似,不同的是指针指向的是就绪索引表和阻塞索引表,如下图所示。
在这里插入图片描述

4、进程的特征

进程的特征有动态性、并发性、独立性、异步性和结构性。
动态性是进程最基本的特征,进程是程序的一次执行过程,是动态地产生、变化和消亡的。
并发性是指内存中有多个进程实体,各进程可以并发执行。
独立性指的是进程是能够独立运行、独立获得资源和独立接受调度的基本单位。(进程是资源分配、接受调度的基本单位)
异步性指的是各进程按各自独立的、不可预知的速度向前推进,操作系统要提供进程同步机制来解决异步的问题。异步性会导致并发程序执行结果的不确定性。
结构性指的是每个进程都会配置一个PCB,从结构上看,进程由程序段、数据段和PCB组成。
对进程的定义、组成、组织方式和特征简单的总结一下,如下图所示。
请添加图片描述


二、进程的状态与转换

1、进程的状态

进程的三种基本状态为运行态(Running)、就绪态(Ready)和阻塞态(Blocked,也称等待态Waiting)。
运行态,进程占有CPU并在CPU上运行,单核处理机环境下,每一时刻最多只有一个进程处于运行态,双核环境下则可以有两个进程处于运行态。
就绪态,即已经具备运行条件,但由于没有空闲的CPU而暂时不能运行。这种状态下,进程已经拥有了除处理机之外的所有需要的资源,一旦获得处理机便可立即进入运行态开始运行。
阻塞态,因等待某一事件而暂时不能运行,由于CPU是计算机中最昂贵的部件,因此需要先将其他进程需要的资源(这里的资源包括打印机,磁盘等)分配到位,才能得到CPU的服务。
除了以上的三种基本状态,还有其他两个状态,即创建态(New, 也称新建态)和终止态(Terminated, 也称结束态)。
创建态,进程正在被创建,操作系统为进程分配资源和初始化PCB。
终止态,进程正在从系统中撤销,操作系统会回收进程拥有的资源,撤销PCB。

2、进程状态的转化

进程状态的转化过程由下图所示。
请添加图片描述
需要注意的是,不能由阻塞态直接转换为运行态,也不能由就绪态直接转换为阻塞态。因为阻塞态下其他的必要条件都没有准备好,无法直接进入运行态。就绪态也无法直接进入阻塞态,因为进入阻塞态是进程自身做出的主动行为,所以需要进程在运行时才能发出该请求。
对进程的状态与转换简单的总结一下,如下图所示。
请添加图片描述


三、进程控制

1、进程控制

进程控制的主要功能是对系统中的所有进程实施有效的管理,它具有创建新进程、撤销已有进程、实现进程状态转换等功能。
进程的控制过程如下图所示。
请添加图片描述
进程的控制过程简单来说就是上面提到的五种状态之间的切换。

2、原语

进程的控制通过原语来实现。原语的特点是执行期间不允许中断,只能一次性完成。这种不可中断的操作即为原子操作。
原语采用关中断指令开中断指令实现,如下图所示。
在这里插入图片描述
执行原语时,会先执行关中断指令执行,该指令执行后,如果有外部中断信号进入,则该信号会被暂时忽略,从而保证了原语不被中断。原语执行完成后会执行开中断指令,此后再有外部中断信号,则会转入中断处理程序进行处理。
关中断和开中断指令的权限非常大,因此,原语是运行在核心态下的
原语要完成的工作是
①更新PCB中的信息,包括修改进程状态标志(所有的进程控制原语一定会修改进程状态标志)、将运行环境保存到PCB(剥夺当前运行进程的CPU使用权必然需要保存其运行环境)以及从PCB恢复运行环境(某进程开始运行前必然要恢复其运行环境)。
②将PCB插入到合适的队列。
③分配和回收资源。
进程创建过程中用到的创建原语和引起进程创建的事件如下图所示。
在这里插入图片描述
进程终止过程中用到的撤销原语和引起进程终止的事件如下图所示。
在这里插入图片描述
进程的阻塞和唤醒过程中用到的阻塞原语和唤醒原语和引起进程阻塞和唤醒的事件如下图所示。阻塞原语和唤醒原语必须成对使用。
在这里插入图片描述
进程切换过程中用到的切换原语和引起进程切换的事件如下图所示。
在这里插入图片描述
对进程控制简单的总结一下,如下图所示。
在这里插入图片描述


四、进程通信

进程通信就是进程间的信息交换。进程通信的方式有:共享存储、管道通信和消息传递。
进程是分配系统资源的单位(也包括内存地址空间),因此各进程拥有的内存地址空间相互独立。此外,为了保证系统安全,一个进程不能直接访问另外一个进程的地址空间,但是进程之间的信息交换有时是必要的,所以就有了进程通信。

1、共享存储

共享存储分为基于数据结构的共享和基于存储区的共享。
基于数据结构的共享:共享空间里只能存放固定的数据结构,比如一个长度为10的数组,这种方式速度慢、限制多,是一种低级的通信方式。
基于存储区的共享:在内存中划出一块共享存储区,数据的形式、存放位置都由进程控制,而不是操作系统,相比于基于数据结构的共享方式,这种方式速度更快,是一种高级的通信方式。
下图是共享存储的示意图,它是通过引入一个共享空间实现的。
在这里插入图片描述
需要注意的是,两个进程对于共享空间的访问必须是互斥的,如果进程1正在往共享空间里写数据,进程2是不能访问共享空间的,只有进程1释放了共享空间,进程2才能访问。
这里的互斥操作是通过操作系统提供的同步互斥工具实现的,比如P、V操作。

2、管道通信

管道是指用于连接读写进程的一个共享文件,又名pipe文件,它是在内存中开辟的一个大小固定的缓冲区。
下图是一个半双工的管道通信示意图。
加粗样式
如果要实现双向同时通信,则需要再引入一个管道,一个管道负责从左到右,另一个管道负责从右到左,如下图所示。
在这里插入图片描述
管道通信的要点
管道只能采用半双工通信,某一时间段内只能实现单向的传输,如果要实现双向同时通信,则需要设置两个管道。
各进程要互斥的访问管道
③数据以字符流的形式写入管道,当管道写满时,写进程的write()系统调用将被阻塞,等待读进程将数据读出。当读进程将数据全部取走后,管道变空,此时读进程的read()系统调用将被阻塞。
如果没写满,就不允许读;同样地,如果没读空,就不允许写。
数据一旦被读出,就从管道中被抛弃,这就意味着读进程最多只能有一个,否则可能会有读错数据的情况。

3、消息传递

进程间的数据交换以格式化的消息为单位,进程通过操作系统提供的发送消息接收消息两个原语进行数据交换。
一个格式化的消息包括消息头消息体,其中消息头包括发送进程的ID、接收进程的ID、消息类型、消息长度等格式化信息。(相当于计算机网络中发送的报文
消息传递包括直接通信方式和间接通信方式。
直接通信方式:消息直接挂到接收进程的消息缓冲队列上,其示意图如下图所示。
在这里插入图片描述
间接通信方式:消息先发送到中间实体(这里的中间实体就是信箱)中,该方式也称为信箱通信方式,其示意图如下图所示。
在这里插入图片描述
对进程通信简单的总结一下,如下图所示。
在这里插入图片描述


五、线程概念和多线程模型

1、线程的概念及作用

有的进程需要“同时”做很多事,而传统的进程只能串行地执行一系列程序,因此引入线程(Thread)来增加并发度
传统的进程是程序执行流的最小单位,但引入线程后,线程成为了程序执行流的最小单位。可以把线程理解为轻量级的进程。
线程是一个基本的CPU执行单元,也是程序执行流的最小单位。引入线程之后,不仅进程之间可以并发,进程内的各线程之间也可以并发,从而进一步提升了系统的并发度,使得一个进程内也可以并发处理各种任务(如在QQ内同时视频、文字聊天、传输文件等操作)。
引入线程后,进程只作为除CPU之外的系统资源分配的基本单位(比如打印机、内存地址空间等都是分配给进程的),而线程做调度的基本单位。
下图是引入线程后所带来的变化。
在这里插入图片描述引入线程后,资源的分配和调度、并发性和系统开销方面都有了一定的改变,线程做调度的基本单位,并发性提升,系统开销减小。

2、线程的属性

线程的一些属性如下图所示。
在这里插入图片描述
可以看到,线程有一些和进程比较相似的地方,比如线程ID、线程控制块(TCB,Thread Control Block)以及三种基本状态等,引入线程会使得系统的开销减小,这是比较有利的。

3、线程的实现方式

线程的实现方式包括用户级线程(ULT, User-Level Thread)和内核级线程(KLT, Kernel-Level Thread),内核级线程又称内核支持的线程。
用户级线程的示意图如下图所示。
在这里插入图片描述
用户级线程由应用程序通过线程库实现,所有的线程管理工作都由应用程序负责,包括线程的切换。在用户级线程中,线程的切换可以在用户态下完成,无需操作系统的干预。
用户级线程即从用户的视角看有多个线程,但在操作系统内核来看,并意识不到线程的存在。即用户级线程对用户不透明,对操作系统透明。
简单理解用户级线程就是从用户视角能看到的线程。
内核级线程的示意图如下图所示。
在这里插入图片描述
内核级线程的管理工作由操作系统内核完成,线程调度、切换等工作都由内核负责,所以内核级线程的切换需要在核心态下才能完成。
同样地,简单理解内核级线程就是从操作系统内核视角能看到的线程。
内核级线程才是处理机分配的单位。
举例:下图是一个由两个内核级线程和三个用户级线程构成的进程模型。
在这里插入图片描述
在用户看来,这个进程中有三个线程,但是即使该进程在拥有四核处理机的计算机上运行,最多也只能分配到两个核,也就是说,最多只有两个用户线程能够并行执行。因为该进程只有两个内核级线程,而内核级线程才是处理机分配的单位。

4、多线程模型

在同时支持用户级线程和内核级线程的系统中,由几个用户级线程映射到几个内核级线程的问题便引出了多线程模型问题。
多对一模型的示意图如下图所示。
在这里插入图片描述
多对一模型顾名思义就是多个用户级线程映射到一个内核级线程,每个用户进程只对应一个内核级线程。
多对一模型的优点:用户级线程的切换在用户空间即可完成,不需要切换到核心态,线程管理的系统开销小,效率高。
多对一模型的缺点:当一个用户级线程被阻塞后,整个进程都会被阻塞,并发度不高,多个线程不可在多核处理机上并行运行。
一对一模型的示意图如下图所示。
在这里插入图片描述一对一模型也就是一个用户级线程映射到一个内核级线程,每个用户进程有与用户线程同等数量的内核级线程。
一对一模型的优点:当一个用户级线程被阻塞后,别的用户级线程还可以继续执行,并发能力强,多线程可在多核处理机上并行执行。
一对一模型的缺点:一个用户进程会占用多个内核级线程,线程切换由操作系统内核完成,需在核心态下完成这一工作,因此线程管理的成本高,开销大。
多对多模型的示意图如下图所示。在这里插入图片描述
多对多模型就是 n 个用户级线程映射到 m 个内核级线程,其中 n >= m,每个用户进程对应 m 个内核级线程。
多对多模型克服了多对一模型并发度不高的缺点,又克服了一对一模型中一个用户进程占用太多内核级线程和开销太大的缺点,是一个很好地折中模型。
对线程概念和多线程模型简单的总结一下,如下图所示。
请添加图片描述


总结

以上就是操作系统——进程和线程相关知识的所有内容了,进程是操作系统中很重要的一个概念,本节介绍到的线程也是,注意区分两者的联系与区别,这样才能更好地掌握其功能和作用并加以运用!
参考视频:
进程的定义、组成、组织方式和特征
进程的状态与转换
进程控制
进程通信
线程概念和多线程模型


版权声明:本文为weixin_42570192原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。