《计算机操作系统-第五章》之线程与多线程模型

简介: 《计算机操作系统-第五章》之线程与多线程模型

文章目录

1.线程

为什么需要线程?

2.什么是线程?

2.1引入线程后的变化

2.2线程的属性

2.3线程的实现方式

2.3.1用户级线程

2.3.2内核级线程

2.3.3内核级线程与用户级线程同在

3.多线程模型

3.1多对一模型

3.2一对一模型

3.3多对多模型

4.处理机调度

4.1高级调度(作业调度)

4.4中级调度(内存调度)

4.5低级调度(进程调度)

1.线程

为什么需要线程?

在很久很久以前,系统中各个程序只能串行执行,也就是qq音乐和qq没法同时运行。后来引入进程,qq和qq音乐就可以并发的执行了。但是这里有个问题,比如qq不仅可以同时文字聊天还可以视频聊天,而我们又知道进程是程序的一次执行,这些功能显然是不可能有一个程序的顺序,如果是按照顺序执行,那么qq就无法做到能同时完成多个功能。因此就引入了线程,来增加并发度。

引入线程前,传统的进程就是执行流的最小单位,假设内存中存在两个进程,分别为进程1和进程2,那么CPU就要被这两个进程并发使用。当引入线程后进程里面可以拥有对个线程,那么CPU就是给进程中的线程并发执行。这样就可以达到qq既可以文字聊天也可以视频聊天。

2.什么是线程?

可以把线程理解为轻量级的进程,线程的创建和回收所消耗的资源远远小于进程的创建和销毁。有了线程后,线程就成了CPU一个基本的执行单元,即程序流的最小单位。

注意

1.引入线程后,进程只作为除CPU之外的系统资源的分配单位(如内存空间)

2.引入线程后,不仅仅是进程之间可以并发,进程内的各线程之间也就可以并发,从而提高了并发度,使得一个进程内也可以处理各种任务

2.1引入线程后的变化

从资源分配,调度的角度来看

  1. 1.传统进程机制中,进程是资源分配,调度的基本单位
  2. 2.引入进程后,进程是资源分配的基本单位,线程是调度的基本单位

从并发性来看

  1. 1.传统进程机制中,只能进程间并发
  2. 2.引入线程后,各线程间也能并发,提高了并发度

从系统开销角度来看

  1. 1.传统的进程间并发,需要切换进程的运行环境,系统开销大
  2. 2.线程间并发,如果是同一个进程内的线程切换,则不需要切换进程环境,系统开销小
  3. 3.引入线程后,并发所带来的系统开销小。

2.2线程的属性

  1. 1.每个线程都有一个线程ID,线程控制块(TCB)
  2. 2.线程几乎不拥有系统资源
  1. 3.同一进程的不同线程间共享进程的资源
  2. 4.由于共享内存地址空间,同一进程中的线程间通信甚至需要系统干预
  3. 5.不同进程中的线程切换,会引起进程切换
  4. 6.多核CPU,各个线程可占用不同的CPU

2.3线程的实现方式

2.3.1用户级线程

用户级线程由应用程序通过线程库是实现。所有的线程管理工作都由应用程序负责(包括线程切换)。用户级线程中,线程切换可以在用户态下即可完成,无需操作系统干预。在用户看来,是有多个线程.但是在操作系统内核看来,并没有意识到线程的存在,而是意识到进程的存在,因此调度的基本单位为进程。

如图所示

2.3.2内核级线程

内核级线程的管理工作由操作系统内核完成。线程调度,切换等工作都由内核完成,因此内核级线程的切换必然需要在核心态下才能完成。从内核角度来看内存中有三个线程,一个进程。

如图所示

2.3.3内核级线程与用户级线程同在

两者结合,也就是将n个用户级线程映射到m个内核级线程上(n>=m)

如图所示

操作系统看的见内核级线程,因此只有内核级线程才是处理机分配的单位。举个栗子,上图中该进程有2个内核级线程,三个用户级线程,站在用户角度有三个线程。当该进程处于多核CPU的计算机上运行时,也最多只能分配2个CPU核心,最多只有2个用户级线程运行 。

3.多线程模型

在同时支持用户级线程和内核级线程的系统中,由几个用户级线程映射到几个内核级线程的问题引出了多线程模型问题

3.1多对一模型

多个用户级线程映射到一个内核级线程。每个用户进程只对应一个内核级线程。

如图所示

优点:用户线程的切换在用户空间即可完成,无需切换大到核心态,线程管理的系统开销小,效率高。

缺点:当一个用户级线程被阻塞后,整个进程后悔被阻塞,并发度不高。多个线程不可以在多核处理机上并发运行。

3.2一对一模型

一个用户级线程映射到一个内核级线程。每个用户进程有与用户级线程同数量的内核级线程

如图所示

优点

当一个线程被阻塞后,别的线程还可以继续执行,并发能力强。多线程可在多核处理机上并发执行。

缺点

一个用户进程会占用多个内核级线程,线程切换由操作系统内核完成,需要切换到核心态,因此线程管理的成本高,开销大。

3.3多对多模型

n个用户级线程映射到m个内核级线程。每个用户级进程对应m个内核级线程。

如图所示

该模型其前两种模型的优点,克服了多对一模型并发度不高的缺点,又克服了一对一模型中一个用户进程占用太多内核级线程,开销太大的缺点。

4.处理机调度

现实世界里,当一群人去银行办事,普通用户则是按时间顺序排好队依次进入银行,而VIP客户则可以优先被服务。在计算机世界里,当有一堆任务要处理,但是由于资源有限(银行),这些事没办法同时处理.这就需要确定某种规则(VIP/时间顺序)来决定处理任务的顺序,这就是调度研究的问题。

在多道程序系统中,进程的数量是远远大于处理机(CPU)的数量,这样不可能同时并发的执行的处理各个进程。处理机调度,就是从就绪队列中按照一定的算法选择一个进程并将处理机分配给它运行,以实现进程的并发执行。

4.1高级调度(作业调度)

由于内存空间有限,有时无法将用户提交的作业全部放入内存中,因此就需要确定某种规则来决定将作业调入内存的顺序。

高级调度:按照一定的原则从外存上处于后备队列的作业中挑选一个(或多个)作业,给他们分配内存等必要资源,并建立相应的进程(建立PCB),以使它获得竞争处理机的权利。

高级调度是外存与内存之间的调度。每个作业只调入一次,调出一次。作业调入时会建立相应的PCB,作业调出时才撤销PCB。高级调度主要是指调入的问题,因为只有调入的时机需要操作系统来确定,但调出的时机必然是作业运行结束才调出。

4.4中级调度(内存调度)

引入虚拟存储技术之后,可将暂时不能运行的进程调至外存等待。等它重新具备了

运行条件且内存又稍有空闲时,再重新调入内存。这样做的目的就是为了提高内存利用率和系统吞吐量。

暂时调到外存等待的进程状态为挂起转态。注意,PCB并不发一起调度到外存,而是会常驻内存.PCB中会记录进程数据在外存中的存放位置,进程转态等信息,

中级调度:就是要决定将那个处于挂起转态的进程中重新调入内存。一个进程可能会被多次调出,调入内存,因此中级调度发生的频率要比高级频率度更高。

七状态模型

暂时调到外存等待的进程状态为挂起状态(挂起态)

挂起态又可以分为就绪挂起,阻塞挂起两种状态

如图所示

注意挂起和阻塞的区别,两种状态都是暂时不能获得CPU的服务,但挂起状态是将进程映像调到外存去了,而阻塞态进程映像还在内幕内存中。

4.5低级调度(进程调度)

其主要任务是按照某种方法从就绪队列中选取一个进程,将处理机分配给它。

进程调度是进程并发执行的基础,是操作系统中最基本的一种调度。进程的调度的频率很高,一般几十毫一次。

最后的话

各位看官如果觉得文章写得不错,点赞评论关注走一波!谢谢啦!。如果你想变强那么点我点我 牛客网

相关实践学习
CentOS 7迁移Anolis OS 7
龙蜥操作系统Anolis OS的体验。Anolis OS 7生态上和依赖管理上保持跟CentOS 7.x兼容,一键式迁移脚本centos2anolis.py。本文为您介绍如何通过AOMS迁移工具实现CentOS 7.x到Anolis OS 7的迁移。
相关文章
|
11天前
|
UED 开发者 Python
探索操作系统的心脏:理解进程与线程
【8月更文挑战第31天】在数字世界的海洋中,操作系统犹如一艘巨轮,其稳定航行依赖于精密的进程与线程机制。本文将揭开这一机制的神秘面纱,通过深入浅出的语言和直观的代码示例,引领读者从理论到实践,体验进程与线程的魅力。我们将从基础概念出发,逐步深入到它们之间的联系与区别,最后探讨如何在编程实践中高效运用这些知识。无论你是初学者还是有经验的开发者,这篇文章都将为你的技术之旅增添新的航标。
|
1天前
|
消息中间件 存储 NoSQL
剖析 Redis List 消息队列的三种消费线程模型
Redis 列表(List)是一种简单的字符串列表,它的底层实现是一个双向链表。 生产环境,很多公司都将 Redis 列表应用于轻量级消息队列 。这篇文章,我们聊聊如何使用 List 命令实现消息队列的功能以及剖析消费者线程模型 。
28 20
剖析 Redis List 消息队列的三种消费线程模型
|
8天前
|
存储 Ubuntu Linux
C语言 多线程编程(1) 初识线程和条件变量
本文档详细介绍了多线程的概念、相关命令及线程的操作方法。首先解释了线程的定义及其与进程的关系,接着对比了线程与进程的区别。随后介绍了如何在 Linux 系统中使用 `pidstat`、`top` 和 `ps` 命令查看线程信息。文档还探讨了多进程和多线程模式各自的优缺点及适用场景,并详细讲解了如何使用 POSIX 线程库创建、退出、等待和取消线程。此外,还介绍了线程分离的概念和方法,并提供了多个示例代码帮助理解。最后,深入探讨了线程间的通讯机制、互斥锁和条件变量的使用,通过具体示例展示了如何实现生产者与消费者的同步模型。
|
11天前
|
调度 开发者 Python
深入浅出操作系统:进程与线程的奥秘
【8月更文挑战第31天】 本文将带你探索操作系统中的核心概念——进程与线程。通过浅显易懂的语言和实际代码示例,我们将一起理解它们的定义、区别以及在操作系统中的作用。无论你是编程新手还是有一定经验的开发者,这篇文章都将为你打开一扇了解计算机内部工作原理的新窗口。
|
11天前
|
消息中间件 Unix Linux
深入浅出操作系统:进程与线程的奥秘
【8月更文挑战第31天】本文将带你一探操作系统中最为神秘的两个概念——进程和线程。我们将从基础的定义出发,逐步深入到它们在操作系统中的实现原理,并通过代码示例揭示它们在实际编程中的应用。无论你是初学者还是有一定经验的开发者,这篇文章都将为你提供新的视角和理解。
|
11天前
|
开发者 Python
深入浅出操作系统:进程与线程的奥秘
【8月更文挑战第31天】在数字世界的幕后,操作系统扮演着至关重要的角色。本文将揭开进程与线程这两个核心概念的神秘面纱,通过生动的比喻和实际代码示例,带领读者理解它们的定义、区别以及如何在编程中运用这些知识来优化软件的性能。无论你是初学者还是有一定经验的开发者,这篇文章都将为你提供新的视角和实用技巧。
|
11天前
探索操作系统中的线程同步机制
【8月更文挑战第31天】在多线程编程领域,理解并实现线程同步是至关重要的。本文通过浅显易懂的语言和生动的比喻,带你走进线程同步的世界,从互斥锁到信号量,再到条件变量,逐步揭示它们在协调线程行为中的作用。我们将一起动手实践,用代码示例加深对线程同步机制的理解和应用。
|
16天前
|
存储 监控 Java
Java多线程优化:提高线程池性能的技巧与实践
Java多线程优化:提高线程池性能的技巧与实践
43 1
|
16天前
|
监控 安全 Java
Java多线程调试技巧:如何定位和解决线程安全问题
Java多线程调试技巧:如何定位和解决线程安全问题
66 2

热门文章

最新文章