《操作系统》——进程与线程

简介: 《操作系统》——进程与线程

在上一期博客中,我们学习了关于操作系统中计算机系统概述的基本知识。今天,我将带领学习的是关于操作系统中一个非常重要的概念——进程与线程!!!




前言

在传统的操作系统中,为了提高资源利用率和系统吞吐量,通常采用多道程序技术,将多个程序同时装入内存,并使之并发运行,传统意义上的程序不再能独立运行。此时,作为资源分配和独立运行的基本单位都是进程。操作系统所具有的四大特征也都是基于进进程而形成的,并从进程的角度对操作系统进行研究。可见,在操作系统中,进程是一个极其重要的概念。

 

在学习本文时,请读者思考以下问题:

  • 1)为什么要引入进程
  • 2)什么是进程?进程有什么组成?
  • 3)进程是如何解决问题的?

希望读者带着上述问题去学习本节内容,并在学习的过程中多多思考,从而更好的理解相关知识!!


(一)进程的基本概念和特征

首先,我们从直观的事物出发去理解所谓的进程:

  • 首先,我在我自己的电脑里打开认为管理器,此时我们就可以从任务管理器中看到电脑此时正在运行的进程:

  • 此时,当我们想运行 画图的话,我们就可以看到在我们的任务管理器中看到 画图 的条目信息:

紧接着,当我们打开三个 画图 时,我们在进程管理中可以看到三个 画图 条目信息:

对于同一个程序,进行多次执行,每次看到的都是不同的进程;

因此,我们不难发现程序就是存放在磁盘里的一些可执行文件,就是一些列的指令集合,并且它是静态的。

1、进程的概念

进程的引入:

  1. 在多道程序环境下,允许多个程序并发执行,此时它们将失去封闭性,并具有间断性及不可生的特征;
  2. 为此引入了进程( Process )的概念,以便更好地描述和控制程序的并发执行,实现操作系统的并发性和共享性(最基本的两个特性)。

PCB的提出:

对于上述的的 画图,我们可以发现在同一时间运行了三个进程,此时问题就来了:

  • 操作系统是这些进程的管理者,它是如何区分各个进程的呢?

💨  答案是在创建进程时,操作系统在背后会为该进程分配一个唯一的、不重复的身份ID——“PID”。

因此,现在我们可以知道对于上述 画图程序来说,虽然同时运行了三个进程名字都叫 画图,但是在各个进程的背后都有各自的 PID 来唯一标识!!!

其次,OS除了对进程分配PID外,还有记录很多东西,例如进程的运行状况、记录给进程分配了哪些资源等。此时问题又来了,对于OS分配的这些东西,要如何管理呢?

对于这个问题,就引出了进程PCB的概念:

  1. 了使参与并发执行的每个程序(含数据)都能独立地运行,必须为之配置一个专门的数据结构,称为进程控制块( Process Control Block , PCB );
  2. 系统利用 PCB 来描述进程的基本情况和运行状态,进而控制和管理进程;
  3. 相应地,由程序段、相关数据段和 PCB 三部分构成了进程实体进程映像)

 

上述我们已经说过PCB是给OS系统使用的,而对于程序段和数据段 相应的就是给进程自己使用的。

知识滚雪球

💨 在之前的学习中我们已经知道程序是如何运行的,在运行之前具体会经过哪几步的操作,接下来我再给大家对其过程进一步的细化讲解。

  1. 当我们写完一个程序之后,经过编译链接等相关的步奏,最终会形成可执行文件(像大家熟悉的Windows电脑就是 .exe文件),对于这些可执行文件平时是存放在硬盘之中的,而可执行文件中保存的就是一些指令序列;
  2. 而当程序运行之前,需要把它从硬盘读入内存中,OS并为它建立一个相对应的进程;
  3. 此时除了建立PCB外,还需要把程序的指令序列读入到内存当中,因此我们就把这些指令序列称为数据段,而CPU执行的过程就是从内存中读出一个一个的指令;
  4. 其次,在程序的执行过程中还可能会产生一些中间数据,对于这些内容需要放入内存中,为了存放这些数据,需要在内存中创建一个名为程序段的区域来存放这些数据。

 

小结:

  • 操作系统需要对各个并发运行的进程进行管理操作,但凡管理时需要的资源,都会被放在PCB中。

🔥值得注意的是,进程映像静态进程则动态


进程创建的实质:

  • 所谓创建进程,实质上是创建进程实体中的 PCB ;
  • 而撤销进程,实质上是撤销 PCB

👉 注意: PCB 是进程存在的唯一标志!👈

不同的角度,进程可以有不同的定义,比较典型的定义有:

  1. 进程是程序的一次执行过程;
  2. 进程是一个程序及其数据在处理机上顺序执行时所发生的活动;
  3. 进程是具有独立功能的程序在一个数据集合上运行的过程,它是系统讲行资源分配和调度的基本单位。

2、进程的特征

进程是由多道程序的并发执行而引出的,它和程序是两个截然不同的概念。进程的基本特征
是对比单个程序的顺序执行提出的,也是对进程管理提出的基本要求。

  • 1)动态性。进程是程序的一次执行,它有着创建、活动、暂停、终止等过程,具有一定的生命周期,是动态地产生、变化和消亡的。动态性是进程最基本的特征。
  • 2)并发性。指多个进程实体同存于内存中,能在一段时间内同时运行。引入进程的目的就是使进程能和其他进程并发执行。并发性是进程的重要特征,也是操作系统的重要特征。
  • 3)独立性。指进程实体是一个能独立运行、独立获得资源和独立接受调度的基本单位。凡未建立 PCB 的程序,都不能作为一个独立的单位参与运行。
  • 4)异步性。由于进程的相互制约,使得进程按各自独立的、不可预知的速度向前推进。异步性会导致执行结果的不可再现性,为此在操作系统中必须配置相应的进程同步机制。

(二)进程的状态与切换

进程在其生命周期内,由于系统中各进程之间的相互制约及系统的运行环境的变化,使得进程的状态也在不断地发生变化。通常进程有以下5种状态,前3种是进程的基本状态。

1、状态

1️⃣运行态

  1. 进程正在处理机上运行。在单处理机中,每个时刻只有一个进程处于运行态;
  2. 一旦进程处于运行态,意味着此时CPU正在处理这个进程背后的那个程序,即执行程序执行中产生的指令序列

2️⃣就绪态

  1. 进程获得了除处理机外的一切所需资源,一旦得到处理机,便可立即运行;
  2. 系统中处于就绪状态的进程可能有多个,通常将它们排成一个队列,称为就绪队列。

3️⃣阻塞态

  1. 又称等待态。进程正在等待某一事件而暂停运行,如等待某资源为可用(不包括处理机)或等待输入/输出完成。即使处理机空闲,该进程也不能运行。
  2. 系统通常将处于阻塞态的进程也排成一个队列,甚至根据阻塞原因的不同,设置多个阻塞队列。

4️⃣ 创建态

在上述可执行文件加载到内存中,我们已经知道当加载到内存后,操作系统会其创建一个进程,此时进程所处的状态即为 “创建态”。

💨 进程正在被创建,尚未转到就绪态。

创建进程需要多个步骤:

  1. 首先申请一个空白 PCB ,并向 PCB 中填写用于控制和管理进程的信息;
  2. 然后为该进程分配运行时所必须的资源;
  3. 最后把该进程转入就绪态并插入就绪队列;

但是,如果进程所需的资源尚不能得到满足,如内存不足,则创建工作尚未完成,进程此时所处的状态称为创建态。

5️⃣结束态

进程正从系统中消失,可能是进程正常结束或其他原因退出运行。进程需要结束运行时,系统首先将该进程置为结束态,然后进一步处理资源释放和回收等工作。

 


2、切换

3种基本状态之间的转换如下:

  1. 就绪态一运行态:处于就绪态的进程被调度后,获得处理机资源(分派处理机时间片),于是进程由就绪态转换为运行态。
  2. 运行态一就绪态:处于运行态的进程在时间片用完后,不得不让出处理机,从而进程由运行态转换为就绪态。此外,在可剥夺的操作系统中,当有更高优先级的进程就绪时,调度程序将正在执行的进程转换为就绪态,让更高优先级的进程执行。
  3. 运行态一阻塞态:进程请求某一资源(如外设)的使用和分配或等待某一事件的发生(如 I / O 操作的完成)时,它就从运行态转换为阻塞态。进程以系统调用的形式请求操作系统提供服务,这是一种特殊的、由运行用户态程序调用操作系统内核过程的形式。
  4. 阻塞态一就绪态:进程等待的事件到来时,如 I / O 操作结束或中断结束时,中断处理程序必须把相应进程的状态由阻塞态转换为就绪态。

 


(三)进程的组织

前述:

  1. 为了便于对计算机中的各类资源(包括硬件和信息)的使用和管理, OS 将它们抽象为相应的各种数据结构,以及提供一组对资源进行操作的命令,用户可利用这些数据结构及操作命令来执行相关的操作,而无需关心其实现的具体细节;
  2. 另一方面,操作系统作为计算机资源的管理者,尤其是为了协调诸多用户对系统中共享资源的使用,它还必须记录和查询各种资源的使用及各类进程运行情况的信息。 OS 对于这些信息的组织和维护也是通过建立和维护各种数据结构的方式来实现的。

1、操作系统中用于管理控制的数据结构

在计算机系统中,对于每个资源和每个进程都设置了一个数据结构,用于表征其实体,我们称之为资源信息表或进程信息表,其中包含了资源或进程的标识、描述、状态等信息以及一批指针。通过这些指针,可以将同类资源或进程的信息表,或者同一进程所占用的资源信息表分类链接成不同的队列,便于操作系统进行查找。 通常进程表又被称为进程控制块 PCB 。


2、进程控制块

1️⃣进程控制块PCB的作用

💨进程创建时,操作系统为它新建一个 PCB ,该结构之后常驻内存,任意时刻都可以存取,并在进程结束时删除。 PCB 是进程实体的一部分,是进程存在的唯一标志。

💨进程执行时,系统通过其 PCB 了解进程的现行状态信息,以便操作系统对其进行控制和管理;进程结束时,系统收回其 PCB ,该进程随之消亡。

下面对PCB的具体作用进行阐述:

  1. 当操作系统欲调度某进程运行时,要从该进程的 PCB 中查出其现行状态及优先级;
  2. 在调度到某进程后,要根据其 PCB 中所保存的处理机状态信息,设置该进程恢复运行的现场,并根其 PCB 中的程序和数据的内存始址,找到其程序和数据:
  3. 进程在运行过程中,当需要和与之合作的进程实现同步、通信或访问文件时,也需要访问 PCB ;
  4. 当进程由于某种原因而暂停运行时,又需将其断点的处理机环境保存在 PCB 中。

可见,在进程的整个生命期中,系统总是通过 PCB 对进程进行控制的,亦即系统唯有通过进程的 PCB 才能感知到该进程的存在。

2️⃣PCB中的信息

进程描述信息

  1. 进程标识符:标志各个进程,每个进程都有一个唯一的标识号;
  2. 用户标识符:进程归属的用户,用户标识符的主要为共享和保护信息。

进程控制和管理信息

  1. 进程当前状态:描述进程的状态信息,作为处理机分配调;
  2. 进程优先级:描述进程抢占处理机的优先级,优先级高的进程可优先获得处所使用的输入/输出设备信息。

资源分配清单

  1. 用于说明有关内存地址空间或虚拟地址空间的状况,所打开文件的列表中所使用的输入\输出设备的信息

处理机相关信息

  1. 也称处理机的上下文,主要指处理机中各寄存器的值。当进程态时,处理机的许多信息都在寄存器中。当进程被切换时,处理机状态信息都在相应的 PCB 中,以便在该进程重新执行时,能从断点继续执行。

3️⃣PCB的组织方式

在一个系统中,通常可拥有数十个、数百个乃至数千个 PCB 。为了能对它们加以有效的管理,应该用适当的方式将这些 PCB 组织起来。目前常用的组织方式有以下三种。

(1)线性方式

  • 即将系统中所有的 PCB 都组织在一张线性表中,将该表的首址存放在内存的一个专用区域中。该方式实现简单、开销小,但每次查找时都需要扫描整张表,因此适合进程数目不多的系统。

(2)链接方式

  • 即把具有相同状态进程的 PCB 分别通过 PCB 中的链接字链接成一个队列。这样,可以形成就绪队列、若干个阻塞队列和空白队列等。对就绪队列而言,往往按进程的优先级将 PCB 从高到低进行排列,将优先级高的进程 PCB 排在队列的前面。

(3)索引方式

  • 即系统根据所有进程状态的不同,建立几张索引表,例如,就绪索引表、阻塞索引表等,并把各索引表在内存的首地址记录在内存的一些专用单元中。在每个索引表的表目中,记录具有相应状态的某个 PCB 在 PCB 表中的地址。


3、程序段

程序段就是能被进程调度程序调度到 CPU 执行的程序代码段。注意,程序可被多个进程共享,即多个进程可以运行同一个程序。


 

4、数据段

一个进程的数据段,可以是进程对应的程序加工处理的原始数据,也可以是程序执行时产生的中间或最终结果。


(四)进程控制

进程控制的主要功能是对系统中的所有进程实施有效的管理,它具有创建新进程、撤销进程、实现进程状态转换等功能。在操作系统中,一般把进程控制用的程序段称为原语,原语的特点是执行期间不允许中断,它是一个不可分割的基本单位。


1、进程的创建

1️⃣进程树

为了形象地描述一个进程的家族关系而引入了进程图( Process Graph )。

所谓进程图就是用于描述进程间关系的一棵有向树,如下图所示。图中的结点代表进程。在进程 D 创建了进程 I 之后,称 D 是 I 的父进程( Parent Process ), I 是 D 的子进程( Progeny Process )。

2️⃣引起创建进程的事件

为使程序之间能并发运行,应先为它们分别创建进程。导致一个进程去创建另一个进程的典型事件有四类:

用户登录

  • 在分时系统中,用户在终端键入登录命令后,若登录成功,系统将为该用户建立一个进程,并把它插入就绪队列中。

作业调度

  • 在多道批处理系统中,当作业调度程序按一定的算法调度到某个(些)作业时,便将它(们)装入内存,为它(们)创建进程,并把它(们)插入就绪队列中。

提供服务

  • 当运行中的用户程序提出某种请求后,系统将专门创建一个进程来提供用户所需要的服务,例如,用户程序要求进行文件打印,操作系统将为它创建一个打印进程,这样不仅可使打印进程与该用户进程并发执行,而且还便于计算为完成打印任务所花费的时间。

应用请求

  • 在上述三种情况下,都是由系统内核为用户创建一个新进程;
  • 而这类事件则是由用户进程自己创建新进程,以便使新进程以同创建者进程并发运行的方式完成特定任务。

3️⃣进程的创建过程

引起进程的创建。操作系统创建一个新进程的过程如下(创建原语)

  • 1)为新进程分配一个唯一的进程标识号,并申请一个空白 PCB ( PCB 是有限的)。若 P 请失败,则创建失败。
  • 2)为进程分配其运行所需的资源,如内存、文件、 I / O 设备和 CPU 时等。这些资源或从操作系统获得,或仅从其父进程获得。如果资源不足(如内存),则不是创建失败,而是处于创建态,等待内存资源。
  • 3)初始化 PCB ,主要包括初始化标志信息、初始化处理机状态信息和初始化处理息,以及设置进程的优先级等。
  • 4)若进程就绪队列能够接纳新进程,则将新进程插入就绪队列,等待被调度运行。

2、进程的终止

1️⃣ 引起进程终止的事件

正常结束

  • 表示进程的任务已完成并准备退出运行。

异常结束

  • 表示进程在运行时,发生了某种异常事件,使程序无法继续运行,如存储区越界、保护错、非法指令、特权指令错、运行超时、算术运算错、 I / O 故障等。

外界干预

  • 指进程应外界的请求而终止运行,如操作员或操作系统干预、父进程请求和父进程终止。

2️⃣进程的终止过程

操作系统终止进程的过程如下(终止原语)

  • 1)根据被终止进程的标识符,检索出该进程的 PCB ,从中读出该进程的状态。2)若被终止进程处于执行状态,立即终止该进程的执行,将处理机资源分配给其他进程。
  • 3)若该进程还有子孙进程,则应将其所有子孙进程终止。
  • 4)将该进程所拥有的全部资源,或归还给其父进程,或归还给操作系统。
  • 5)将该 PCB 从所在队列(链表)中删除。

3、进程的阻塞和唤醒

正在执行的进程,由于期待的某些事件未发生,如请求系统资源失败、等待某种操作的完未到达或无新任务可做等,进程便通过调用阻塞原语( Block ),使自己由运行态变阻塞态。

💨 可见,阻塞是进程自身的一种主动行为,也因此只有处于运行态的进程(获得 CPU ),才可能将其转为阻塞态。

阻塞原语的执行过程如下:

  • 1)找到将要被阻塞进程的标识号对应的 PCB ;
  • 2)若该进程为运行态,则保护其现场,将其状态转为阻塞态,停止运行;
  • 3)把该 PCB 插入相应事件的等待队列,将处理机资源调度给其他就绪进程。

当被阻塞进程所期待的事件出现时,如它所启动的 I / O 操作已完成或其所期待的数据已到达,由有关进程(比如,释放该 I / O 设备的进程,或提供数据的进程)调用唤醒原语( Wakeup ),将等待该事件的进程唤醒。

唤醒原语的执行过程如下:

  • 1)在该事件的等待队列中找到相应进程的 PCB ;
  • 2)将其从等待队列中移出,并置其状态为就绪态;
  • 3)把该 PCB 插入就绪队列,等待调度程序调度。

注意:

  1. Block 原语和 Wakeup 原语是一对作用刚好相反的原语,必须成对使用;
  2. 如果在某进程中调用了 Block 原语,则必须在与之合作的或其他相关的进程中安排一条相应的 Wakeup 原语,以便唤醒阻塞进程;
  3. 否则,阻塞进程将会因不能被唤醒而永久地处于阻塞状态。

(五)进程的通信

在我们日常进行信息交流的时候是怎么交流的呢?

  • 我以 抖音为例,当我们想把看到的内容分享给别人时,如果你们之前互相加了好友,那么便可直接分享给他,也可以复制链接或者直接@。对于分享信息的操作,我们就可以看成进程之间进行的通信交流。

接下来,介绍三种主要的通信方式(之后在Linux中我还会对其以代码的形式讲解):

1、共享存储

在通信的进程之间存在一块可直接访问的共享空间,通过对这片共享空间进行写/读操作实进程之间的信息交换。

如下图所示:

在对共享空间进行写/读操作时,需要使用同步互斥工具( P 操作、 V 操作),对共享空间的写/读进行控制。

共享存储分为两种:

  1. 低级方式的共享是基数据结构的共享:
  2. 高级方式的共享则是基于存储区的共享。

💨 操作系统只负责为通信进程提供可享使用的存储空间和同步互斥工具,而数据交换则由用户自己安排读/写指令完成。

注意:

  • 进程空间一般都是独立的,进程运行期间一般不能访问其他进程的空间,想让两进程共享空间,必须通过特殊的系统调用实现,而进程内的线程是自然共享进程空间的。

简单理解就是,甲和乙中间有一个大布袋,甲和乙交换物品是通过大布袋进行的,甲把物放在大布袋里,乙拿走。但乙不能直接到甲的手中拿东西,甲也不能直接到乙的手中拿东西。


2、消息传递

消息传递系统中,进程间的数据交换以格式化的消息( Message )为单位。若通信的进之间不存在可直接访问的共享空间,则必须利用操作系统提供的消息传递方法实现进程通信。

  • 1)直接通信方式。发送进程直接把消息发送给接收进程,并将它挂在接收进程的消息缓冲队列上,接收进程从消息缓冲队列中取得消息。如下图:

  • 2)间接通信方式。发送进程把消息发送到某个中间实体,接收进程从中间实体取得这种中间实体一般称为信箱。该通信方式广泛应用于计算机网络中。如下图:

理解就是,甲要告诉乙某些事情,就要写信,然后通过邮差送给乙。直接通信就送到乙的手上;间接通信就是乙家门口有一个邮箱,邮差把信放到邮箱里。


3、管道通信

管道通信是消息传递的一种特殊方式(如下图)

💨 所谓"管道",是指用于连接一个读进程和一个写进程以实现它们之间的通信的一个共享文件,又名 pipe 文件。

在 Linux 中,管道是一种使用非常频繁的通信机制。从本质上说,管道也是一种文件,但它又和一般的文件有所不同,管道可以克服使用文件进行通信的两个问题。

具体表现如下:

  • 1)限制管道的大小。实际上,管道是一个固定大小的缓冲区。在 Linux 中,该缓冲区的大小为4KB,这使得它的大小不像文件那样不加检验地增长。使用单个固定缓冲区也会带来问题,比如在写管道时可能变满,这种情况发生时,随后对管道的 write ()调用将默认地被阻塞,等待某些数据被读取,以便腾出足够的空间供 write ()调用写。
  • 2)读进程也可能工作得比写进程快。当所有当前进程数据已被读取时,管道变空。当这种情况发生时,一个随后的 read ()调用将默认地被阻塞,等待某些数据被写入,这解决了 read()调用返回文件结束的问题。

🔥 注意:

  1. 从管道读数据是一次性操作,数据一旦被读取,就释放空间以便写更多数据;
  2. 管道只能采用半双工通信,即某一时刻只能单向传输。要实现父子进程互动通信,需定义两个管道。

(六)线程和多线程模型

为了解决多道程序并发执行,引入了进程的概念,在以后长达20年的时间里一直是以进程作为OS进行资源分配和调度的基本单位。知道上个世纪80年代,人们提出了比进程更小的基本单位——线程,试图用它来提高程序的并发执行程序,以进一步改善服务质量。

1、线程的基本概念

线程的引入

  1. 引入进程的目的是更好地使多道程序并发执行,提高资源利用率和系统吞吐量;
  2. 而引入线程的目的则是减小程序在并发执行时所付出的时空开销,提高操作系统的并发性能。

知识点小结

  1. 线程最直接的理解就是"轻量级进程",它是一个基本的 CPU 执行单元,也是程序执行流的最小单元,由线程 ID 、程序计数器、寄存器集合和堆栈组成。
  2. 线程是进程中的一个实体,是被统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的源,但它可与同属一个进程的其他线程共享进程所拥有的全部资源;
  3. 一个线程可以创建和撤销一个线程,同一进程中的多个线程之间可以并发执行;
  4. 由于线程之间的相互制约,致使线程在中运行呈现出间断性;
  5. 线程也有就绪、阻塞和运行三种基本状态。

注意:

  1. 引入线程后,进程的内涵发生了改变,进程只作为除 CPU 外的系统资源的分配单元,而线程则作为处理机的分配单元
  2. 由于一个进程内部有多个线程,若线程的切换发生在同一个进需要很少的时空开销。

2、线程与进程的比较

下面从几个方面对线程和讲程讲行比校:

调度

  1. 在传统的操作系统中,拥有资源和独立调度的基本单位都是进程,每次调度都要进行上下文切换,开销较大;
  2. 在引入线程的操作系统中,线程是独立调度的基本单位,而线程切换的代价远低于进程;
  3. 在同一进程中,线程的切换不会引起进程切换,但从一个进程中的线程切换到另一个进程中的线程时,会引起进程切换。

并发性

  • 在引入线程的操作系统中,不仅进程之间可以并发执行,而且一个进程中的多个线程之间亦可并发执行,甚至不同进程中的线程也能并发执行,从而使操作系统具有更好的并发性,提高了系统资源的利用率和系统的吞吐量。

拥有资源

  • 进程是系统中拥有资源的基本单位,而线程不拥有系统资源(仅有一点必不可少、能保证独立运行的资源),但线程可以访问其隶属进程的系统资源,这主要表现在属于同一进程的所有线程都具有相同的地址空间。要知道,若线程也是拥有资源的单位,则切换线程就需要较大的时空开销,线程这个概念的提出就没有意义。

独立性

  1. 每个进程都拥有独立的地址空间和资源,除了共享全局变量,不允许其他进程访问;
  2. 某进程中的线程对其他进程不可见。同一进程中的不同线程是为了提高并发性及进行相互之间的合作而创建的,它们共享进程的地址空间和资源。

系统开销

  • 在创建或撤销进程时,系统都要为之分配或回收进程控制块 PCB 及其他资源,如内存空间、 I / O 设备等。操作系统为此所付出的开销,明显大于创建或撤销线程时的开销。

支持多处理机系统

  • 对于传统单线程进程,不管有多少处理机,进程只能运行在一个处理机上。对于多线程进程,可以将进程中的多个线程分配到多个处理机上执行。

3、线程的属性

多线程操作系统中的进程已不再是一个基本的执行实体,但它仍具有与执行相关的状态。所谓进程处于"执行"状态,实际上是指该进程中的某线程正在执行。

线程的主要属性如下:

  • 1)线程是一个轻型实体,它不拥有系统资源,但每个线程都应有一个唯一的标识符和一个线程控制块,线程控制块记录了线程执行的寄存器和栈等现场状态。
  • 2)不同的线程可以执行相同的程序,即同一个服务程序被不同的用户调用时,操作系统把它们创建成不同的线程。
  • 3)同一进程中的各个线程共享该进程所拥有的资源。
  • 4)线程是处理机的独立调度单位,多个线程是可以并发执行的。在单 CPU 的计算机系统中,各线程可交替地占用 CPU ;在多 CPU 的计算机系统中,各线程可同时占用不同的 CPU ,若各个 CPU 同时为一个进程内的各线程服务,则可缩短进程的处理时间。
  • 5)一个线程被创建后,便开始了它的生命周期,直至终止。线程在生命周期内会经历阻塞态、就绪态和运行态等各种状态变化。

为什么线程的提出有利于提高系统并发性?

可以这样来理解:

  • 由于有了线程,线程切换时,有可能会发生进程切换,也有可能不发生进程切换,平均而言每次切换所需的开销就变小了,因此能够让更多的线程参与并发,而不会影响到响应时间等问题。

4、线程的状态与切换

与进程一样,各线程之间也存在共享资源和相互合作的制约关系,致使线程在运行时也具有间断性。

相应地,线程在运行时也具有下面三种基本状态:

  1. 执行状态:线程已获得处理机而正在运行。
  2. 就绪状态:线程已具备各种执行条件,只需再获得 CPU 便可立即执行。
  3. 阻塞状态:线程在执行中因某事件受阻而处于暂停状态。

线程这三种基本状态之间的转换和进程基本状态之间的转换是一样的。


5、线程的组织与控制

(1)线程控制块

与进程类似,系统也为每个线程配置一个线程控制块 TCB ,用于记录控制和管理线程的信息。

线程控制块通常包括:

  • ①线程标识符;
  • ②一组寄存器,包括程序计数器、状态寄存器和通用寄存器:
  • ③线程运行状态,用于描述线程正处于何种状态;
  • ④优先级;
  • ⑤线程专有存储区,线程切换时用于保存现场等;
  • ⑥堆栈指针,用于过程调用时保存局部变量及返回地址等。

同一进程中的所有线程都完全共享进程的地址空间和全局变量。各个线程都可以访问进程地址空间的每个单元,所以一个线程可以读、写或甚至清除另一个线程的堆栈。

(2)线程的创建

💨  线程也是具有生命期的,它由创建而产生,由调度而执行,由终止而消亡。相应地,在操作
系统中就有用于创建线程和终止线程的函数(或系统调用)。

💨  用户程序启动时,通常仅有一个称为"初始线程"的线程正在执行,其主要功能是用创建新线程。在创建新线程时,需要利用一个线程创建函数,并提供相应的参数,如指向线程主程序的入口指针、堆栈的大小、线程优先级等。线程创建函数执行完后,将返回一个线程标识符。

(3)线程的终止

💨  当一个线程完成自己的任务后,或线程在运行中出现异常而要被强制终止时,由终止线程调用相应的函数执行终止操作。但是有些线程(主要是系统线程)一旦被建立,便一直运行而不会被终止。通常,线程被终止后并不立即释放它所占有的资源,只有当进程中的其他线程执行了分离函数后终止线程才与资源分离,此时的资源才能被其他线程利用。


6、线程的实现方式

线程的实现可以分为两类:

  1. 用户级线程;
  2. 内核级线程(内核级线程又称为内核支持的线程)

1️⃣用户级线程(ULT)

在用户级线程中,有关线程管理的所有工作都由应用程序在用户空间中完成,内核意识不到线程的存在。

优点如下:

  • ①线程切换不需要转换到内核空间,节省了模式切换的开销;
  • ②调度算法可以是进程专用的,不同的进程可根据自身的需要,对自己的线程选择不同的调度算法。
  • ③用户级线程的实现与操作系统平台无关,对线程管理的代码是属于用户程序的一部分。

缺点如下:

  • ①系统调用的阻塞问题,当线程执行一个系统调用时,不仅该线程被阻塞,而且进程内的所有线程都被阻塞;
  • ②不能发挥多处理机的优势,内核每次分配给一个进程的仅有一个 CPU ,因此进程中仅有一个线程能执行。

 

2️⃣内核级线程(KLT)

在操作系统中,无论是系统进程还是用户进程,都是在操作系统内核的支持下运行的,与内核密相关。

内核级线程同样也是在内核的支持下运行,线程管理的所有工作也是在内核空间内实现的。内核空间也为每个内核级线程设置一个线程控制块,内核根据该控制块感知某线程的存在,并对其加以控制。

具体如下图:

 

优点如下:

  • ①能发挥多处理机的优势,内核能同时调度同一进程中的多个丝行执行;
  • ②如果进程中的一个线程被阻塞,内核可以调度该进程中的其他线程占用处理机运行其他进程中的线程;
  • ③内核支持线程具有很小的数据结构和堆栈,线程切换比较快、开销小;
  • ④内核本身也可采用多线程技术,可以提高系统的执行速度和效率。

缺点如下:

  • 同一进程中的线程切换,需要从用户态转到核心态进行,系统;
  • 这是因为用户进程的线程在用户态运行,而线程调度和管理是在内核实现的。

3️⃣组合方式

有些系统使用组合方式的多线程实现。在组合实现方式中,内核支持多个内核级线程的建立、调度和管理,同时允许用户程序建立、调度和管理用户级线程。一些内核级线程对应多个用户级线程,这是用户级线程通过时分多路复用内核级线程实现的。同一进程中的多个线程可以同时在多处理机上并行执行,且在阻塞一个线程时不需要将整个进程阻塞,所以组合方式能结合 KLT 和 ULT 的优点,并且克服各自的不足。

在线程实现方式的介绍中,提到了通过线程库来创建和管理线程。线程库( thread library )是为程序员提供创建和管理线程的 API 。

实现线程库主要的方法有如下两种:

  • ①在用户空间中提供一个没有内核支持的库。这种库的所有代码和数据结构都位于用户空间中。这意味着,调用库内的一个函数只导致用户空间中的一个本地函数的调用。
  • ②实现由操作系统直接支持的内核级的一个库。对于这种情况,库内的代码和数据结构位于内核空间。调用库中的一个 API 函数通常会导致对内核的系统调用。

目前使用的三种主要线程库是: POSIX Pthreads Windows API Java


7、多线程模型

有些系统同时支持用户线程和内核线程,由于用户级线程和内核级线程连接方式的不同,从而形成了下面三种不同的多线程模型。

1️⃣多对一模型

将多个用户级线程映射到一个内核级线程,这些用户线程一般属于一个进程,线程的调度和管理在用户空间完成。仅当用户线程需要访问内核时,才将其映射到一个内核级线程上,但是每次只允许一个线程进行映射。

 

 

优缺点:

  • 优点:线程管理是在用户空间进行的,因而效率比较高。
  • 缺点:如果一个线程在访问内核时发生阻塞,则整个进程都会被阻塞;在任何时刻,只有一个线程能够访问内核,多个线程不能同时在多个处理机上运行。

2️⃣一对一模型

将每个用户级线程映射到一个内核级线程,如下图所示。

优缺点:

  • 优点:当一个线程被阻塞后,允许调度另一个线程运行,所以并发能力较强。
  • 缺点:每创建一个用户线程,相应地就需要创建一个内核线程,开销较大。

3️⃣多对多模型

将 n 个用户线程映射到 m 个内核级线程上,要求 n ≥ m ,如下图所示。

 

优缺点:

  • 特点:既克服了多对一模型并发度不高的缺点,又克服了一对一模型的一个用户进程占用太多内核级线程而开销太大的缺点。此外,还拥有上述两种模型各自的优点。

(七)问题回答

1、为什么要引入进程?

  1. 在多道程序同时运行的背景下,进程之间需要共享系统资源,因此会导致各程序在执行过程中出现相互制约的关系,程序的执行会表现出间断性的特征。
  2. 这些特征都是在程序的执行过程中发生的,是动态的过程,而传统的程序本身是一组指令的集合,是一个静态的概念,无法描述程序在内存中的执行情况,即我们无法从程序的字面上看出它何时执行、何时停顿,也无法看出它与其他执行程序的关系,因此,程序这个静态概念已不能如实反映程序并发执行过程的特征。
  3. 为了深刻描述程序动态执行过程的性质乃至更好地支持和管理多道程序的并发执行,人们引入了进程的概念。

2、什么是进程?进程由什么组成?

含义:

  • 进程是一个具有独立功能的程序关于某个数据集合的一次运行活动。它可以申请和拥有系统资源,是一个动态的概念,是一个活动的实体。它不只是程序的代码本身,还包括当前的活动,通过程序计数器的值和处理寄存器的内容来表示。

组成:

  • 一个进程实体由程序段、相关数据段和 PCB 三部分构成,其中 PCB 是标志一个进程存在的唯一标识,程序段是进程运行的程序的代码,数据段则存储程序运行过程中相关的一些数据。

3、进程是如何解决问题的?

  • 进程把能够识别程序运行态的一些变量存放在 PCB 中,通过这些变量系统能够更好地了解进程的状况,并在适当时进行进程的切换,以避免一些资源的浪费,甚至划分为更小的调度单位一线程来提高系统的并发度。

(八)总结

到此,本节的知识便全部讲解完毕。接下来,我们回顾本文都学到了什么!

  1. 本节主要介绍什么是进程,并围绕这个问题进行一些阐述和讨论;
  2. 首先,我先给大家讲了为什么要引入进程,从而给大家讲解了关于进程的基本概念和相关特征,知道了PCB是进程存在的唯一标识;
  3. 其次,我们通过了解进程的相关状态,知道了在进程生命周期内的变化关系以及给出了主要的三种状态下的切换场景;
  4. 接下来,我们了解了为了对系统中的进程实施有效的管理,我们提出了进程控制相关的知识;
  5. 然后就是几种常见的进程通信方式,主要包括共享存储、消息队列和管道通信的方式;
  6. 紧接着我们便引出了线程的基本概念。知道了进程是系统分配资源的基本单位,而线程是处理机调度的基本单位;
  7. 最后就是对开篇提出的问题的解答,帮助大家进一步的掌握相关知识。

以上便是文章的全部内容。希望对大家有所帮助,感谢大家的观看!!!

 

相关文章
|
17天前
|
安全 Java 数据处理
Python网络编程基础(Socket编程)多线程/多进程服务器编程
【4月更文挑战第11天】在网络编程中,随着客户端数量的增加,服务器的处理能力成为了一个重要的考量因素。为了处理多个客户端的并发请求,我们通常需要采用多线程或多进程的方式。在本章中,我们将探讨多线程/多进程服务器编程的概念,并通过一个多线程服务器的示例来演示其实现。
|
1月前
|
消息中间件 安全 Linux
线程同步与IPC:单进程多线程环境下的选择与权衡
线程同步与IPC:单进程多线程环境下的选择与权衡
58 0
|
1月前
|
消息中间件 存储 算法
【软件设计师备考 专题 】操作系统的内核(中断控制)、进程、线程概念
【软件设计师备考 专题 】操作系统的内核(中断控制)、进程、线程概念
83 0
|
29天前
|
资源调度 监控 算法
深入理解操作系统:进程管理与调度策略
本文旨在探讨操作系统中进程管理的核心概念及其实现机制,特别是进程调度策略对系统性能的影响。通过分析不同类型操作系统的进程调度算法,我们能够了解这些策略如何平衡响应时间、吞吐量和公平性等关键指标。文章首先介绍进程的基本概念和状态转换,随后深入讨论各种调度策略,如先来先服务(FCFS)、短作业优先(SJF)、轮转(RR)以及多级反馈队列(MLQ)。最后,文章将评估现代操作系统在面对多核处理器和虚拟化技术时,进程调度策略的创新趋势。
|
2天前
|
算法 Linux 调度
深入理解操作系统中的进程调度策略
【4月更文挑战第25天】 在多任务操作系统中,进程调度策略是核心组件之一,它负责决定哪个可运行的进程将获得CPU时间。本文将探讨不同的进程调度算法,包括它们的原理、优缺点以及适用场景。我们将重点分析先到先服务(FCFS)、短作业优先(SJF)、轮转调度(RR)和多级反馈队列(MLFQ)等经典算法,并讨论现代操作系统如Linux和Windows中的实际调度策略。文章的目的是为读者提供对操作系统进程调度机制深度了解,并展示其在系统性能和用户体验中的关键作用。
|
3天前
|
负载均衡 算法 调度
深入理解操作系统中的进程调度策略
【4月更文挑战第25天】 在现代操作系统的核心功能中,进程调度策略扮演着至关重要的角色。本文将详细解析进程调度的基本概念、调度算法的种类及其背后的原理,并探讨它们对系统性能的影响。通过比较不同的调度策略,我们可以更深入地理解操作系统如何管理资源,确保多任务环境下的效率和公平性。
|
4天前
|
Java 数据库连接 数据处理
Python从入门到精通:3.1.2多线程与多进程编程
Python从入门到精通:3.1.2多线程与多进程编程
|
10天前
|
调度 Python
Python多线程、多进程与协程面试题解析
【4月更文挑战第14天】Python并发编程涉及多线程、多进程和协程。面试中,对这些概念的理解和应用是评估候选人的重要标准。本文介绍了它们的基础知识、常见问题和应对策略。多线程在同一进程中并发执行,多进程通过进程间通信实现并发,协程则使用`asyncio`进行轻量级线程控制。面试常遇到的问题包括并发并行混淆、GIL影响多线程性能、进程间通信不当和协程异步IO理解不清。要掌握并发模型,需明确其适用场景,理解GIL、进程间通信和协程调度机制。
28 0
|
20天前
|
算法 Linux 调度
深入理解操作系统的进程调度策略
【4月更文挑战第8天】本文深入剖析了操作系统中的关键组成部分——进程调度策略。首先,我们定义了进程调度并解释了其在资源分配和系统性能中的作用。接着,探讨了几种经典的调度算法,包括先来先服务(FCFS)、短作业优先(SJF)以及多级反馈队列(MLQ)。通过比较这些算法的优缺点,本文揭示了它们在现实世界操作系统中的应用与局限性。最后,文章指出了未来进程调度策略可能的发展方向,特别是针对多核处理器和云计算环境的适应性。
|
20天前
|
算法 调度 UED
深入理解操作系统中的进程调度策略
【4月更文挑战第7天】 在多任务操作系统中,进程调度策略是决定系统性能和响应速度的关键因素之一。本文将探讨现代操作系统中常用的进程调度算法,包括先来先服务、短作业优先、轮转调度以及多级反馈队列等。通过比较各自的优势与局限性,我们旨在为读者提供一个全面的视角,以理解如何根据不同场景选择合适的调度策略,从而优化系统资源分配和提升用户体验。