操作系统 --- 线程(Threads)概念 多线程模型 线程控制与组织

零、学习路线 

一、线程的引入,什么是线程,为什么要引入线程?

      如果说,在OS中引入进程的目的是为了使多个程序能并发执行,以提高资源利用率和系统吞吐量,那么,在操作系统中再引入线程,则是为了减少程序在并发执行时所付出的时空开销,使OS具有更好的并发性。
      首先让我们来回顾进程的两个基本属性:
① 进程是一个可拥有资源的独立单位,一个进程要能独立运行,它必须拥有一定的资源,包括用于存放程序正文、数据的磁盘和内存地址空间,以及它在运行时所需要的I/O设备、已打开的文件、信号量等; 
② 进程同时又是一个可独立调度和分派的基本单位,一个进程要能独立运行,它还必须是一个可独立调度和分派的基本单位。每个进程在系统中有唯一的PCB,系统可根据其PCB感知进程的存在,也可以根据其PCB中的信息,对进程进行调度,还可将断点信息保存在其PCB中。反之,再利用进程PCB中的信息来恢复进程运行的现场。正是由于进程有这两个基本属性,才使进程成为一个能独立运行的基本单位,从而也就构成了进程并发执行的基础。
程序并发执行所需付出的时空开销
      为使程序能并发执行,系统必须进行以下的一系列操作: (1) 创建进程,系统在创建一个进程时,必须为它分配其所必需的、除处理机以外的所有资源,如内存空间、I/O设备,以及建立相应的PCB; (2) 撤消进程,系统在撤消进程时,又必须先对其所占有的资源执行回收操作,然后再撤消PCB; (3) 进程切换,对进程进行上下文切换时,需要保留当前进程的CPU环境,设置新选中进程的CPU环境,因而须花费不少的处理机时间。
线程——作为调度和分派的基本单位
      如何能使多个程序更好地并发执行,同时又尽量减少系统的开销,已成为近年来设计操作系统时所追求的重要目标。有不少研究操作系统的学者们想到,要设法将进程的上述两个属性分开,由OS分开处理,亦即并不把作为调度和分派的基本单位也同时作为拥有资源的单位,以做到“轻装上阵”;而对于拥有资源的基本单位,又不对之施以频繁的切换。正是在这种思想的指导下,形成了线程的概念。


大白话解释如下:

      在还没有引入进程之前,系统中各个程序只能串行执行。比如说听音乐和玩QQ是不能同时进行的,只能先听音乐后玩QQ或者先玩QQ后听音乐。
 
引入了进程之后,听音乐和玩QQ就可以同时实现了。

      在玩QQ时,我们能在QQ中与别人进行视频聊天、文字聊天、传送文件等。
      我们知道,进程是程序的一次执行。但这些功能显然不可能是由一个程序顺序处理就能实现的。因此,有的进程可能需要“同时”做很多事,而传统的进程只能串行地执行一系列程序,即:

      在传统的进程当中,CPU会轮流的为进程服务, 那么这些进程就可以并发的执行,并且每一个进程都会有他自己相应的一系列代码,CPU在为进程服务时,这些代码会一句一句往下执行。因此,在传统的进程机制当中,进程是程序执行流的最小单位。

为此,引入了“线程”,来增加并发度。


      引入了线程之后,CPU的服务对象就不再是进程,而是线程,每一个进程当中可能会包含多个线程,引入线程后,线程成为了程序执行流的最小单位。可以把线程理解为轻量级进程。

      引入线程之后,不仅是进程之间可以并发,进程内的各线程之间也可以并发,从而进一步提升了系统的并发度,使得一个进程内也可以并发处理各种任务(如QQ视频、文字聊天、传文件)。
      引入线程后,进程只作为除CPU之外的系统资源的分配单元(如打印机、内存地址空间等都是分配给进程的)。什么意思呢?假如计算机系统中有各种各样的系统资源,那么这些资源是被分配给进程的,而不是分配给线程。如下图所示:

二、引入线程机制后,有什么变化?

三、线程的属性

线程的属性如下:

  • 线程是处理机调度的单位
  • 多CPU计算机中,各个线程可占用不同的CPU
  • 每个线程都有一个线程ID、线程控制块(TCB)
  • 线程也有就绪、阻塞、运行三种基本状态
  • 线程几乎不拥有系统资源
  • 同一进程的不同线程间共享进程的资源
  • 由于共享内存地址空间,同一进程中的线程间通信甚至无需系统干预
  • 同一进程中的线程切换,不会引起进程切换
  • 不同进程中的线程切换,会引起进程切换
  • 切换同进程内的线程,系统开销很小
  • 切换进程,系统开销较大

线程运行的三个状态  

      与传统的进程一样,在各线程之间也存在着共享资源和相互合作的制约关系,致使线程在运行时也具有间断性。相应地,线程在运行时也具有下述三种基本状态: (1) 执行状态,表示线程已获得处理机而正在运行; (2) 就绪状态,指线程已具备了各种执行条件,只须再获得CPU便可立即执行; (3) 阻塞状态,指线程在执行中因某事件受阻而处于暂停状态,例如,当一个线程执行从键盘读入数据的系统调用时,该线程就被阻塞。

线程控制块TCB

      如同每个进程有一个进程控制块一样,系统也为每个线程配置了一个线程控制块TCB,将所有用于控制和管理线程的信息记录在线程控制块中。

多线程OS中的进程属性 

      通常在多线程OS中的进程都包含了多个线程,并为它们提供资源。OS支持在一个进程中的多个线程能并发执行,但此时的进程就不再作为一个执行的实体。多线程OS中的进程有以下属性: (1) 进程是一个可拥有资源的基本单位。 (2) 多个线程可并发执行。 (3) 进程已不是可执行的实体。

四、线程的实现方式

      线程已在许多系统中实现,但各系统的实现方式并不完全相同。在有的系统中,特别是一些数据库管理系统,如infomix所实现的是用户级线程; 而另一些系统(如Macintosh和OS/2操作系统)所实现的是内核支持线程;还有一些系统如Solaris操作系统,则同时实现了这两种类型的线程。 

4.1 用户级线程ULT(User Level Threads)

      历史背景: 早期的操作系统(如:早期的操作系统(如:早期Unix)只支持进程,不支持线程。当时的“线程”是由线程库实现的)。

      用户级线程是在用户空间中实现的。对线程的创建、 撤消、同步与通信等功能,都无需内核的支持,即用户级线程是与内核无关的。在一个系统中的用户级线程的数目可以达到数百个至数千个。由于这些线程的任务控制块都是设置在用户空间,而线程所执行的操作也无需内核的帮助,因而内核完全不知道用户级线程的存在。

 
举例理解如下:
在前面我们提到过,QQ中可以进行视频通话、文字聊天、传送文件等不同的功能。

      如果要让这三个事情并发的运行的话,那么在不支持线程的系统当中,我们可以分别建立三个进程,这三个进程分别处理其中的三个功能,如下图所示:

那么其实我们可以对代码进行改进,让这三个功能并发的执行,如下图所示:

从代码的角度看,线程其实就是一段代码逻辑。上述三段代码逻辑(三个 if 判断)上可以看作三个“线程”。while 循环就是一个最弱智的“线程库”,线程库完成了对线程的管理工作(如调度)。
 

4.1.1 用户级线程的优点

使用用户级线程方式有许多优点:
(1) 线程切换不需要转换到内核空间,在用户空间即可完成,不需要切换到核心态,线程管理的系统开销小,效率高。
(2) 调度算法可以是进程专用的。
(3) 用户级线程的实现与OS平台无关,因为对于线程管理的代码是属于用户程序的一部分,所有的应用程序都可以对之进行共享。
 

4.1.2 用户级线程的缺点 

而用户级线程方式的主要缺点则在于:
(1) 系统调用的阻塞问题。在基于进程机制的OS中,大多数系统调用将使进程阻塞,因此,当线程执行一个系统调用时,不仅该线程被阻塞,而且,进程内的所有线程会被阻塞。而在内核支持线程方式中,则进程中的其它线程仍然可以运行。
(2) 在单纯的用户级线程实现方式中,多线程应用不能利用多处理机进行多重处理的优点,内核每次分配给一个进程的仅有一个CPU,因此,进程中仅有一个线程能执行,在该线程放弃CPU之前,其它线程只能等待。

4.1.3 总结

1.用户级线程由应用程序通过线程库实现,所有的线程管理工作都由应用程序负责(包括线程切换)。
2.用户级线程中,线程切换可以在用户态下即可完成,无需操作系统干预。
3.在用户看来,是有多个线程。但是在操作系统内核看来,并意识不到线程的存在。“用户级线程”就是“从用户视角看能看到的线程”。

4.2 内核级线程(KST(Kernel Supported Threads))

4.2.1 知识介绍 

      在OS中的所有进程,无论是系统进程还是用户进程,都是在操作系统内核的支持下运行的,是与内核紧密相关的。而内核支持线程KST同样也是在内核的支持下运行的,它们的创建、阻塞、撤消和切换等,也都是在内核空间实现的。为了对内核线程进行控制和管理,在内核空间也为每一个内核线程设置了一个线程控制块,内核根据该控制块而感知某线程的存在,并对其加以控制。当前大多数OS都支持内核支持线程。

4.2.2 内核级线程的优点 

      这种线程实现方式主要有四个主要优点:
(1) 在多处理器系统中,内核能够同时调度同一进程中的多个线程并行执行;
(2) 如果进程中的一个线程被阻塞了,内核可以调度该进程中的其它线程占有处理器运行,并发能力强,也可以运行其它进程中的线程;
(3) 内核支持线程具有很小的数据结构和堆栈,线程的切换比较快,切换开销小;
(4) 内核本身也可以采用多线程技术,可以提高系统的执行速度和效率。 

4.2.3 内核级线程的缺点

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

4.2.4 总结

1.内核级线程的管理工作由操作系统内核完成。
2.线程调度、切换等工作都由内核负责,因此内核级线程的切换必然需要在核心态下才能完成。
3.操作系统会为每个内核级线程建立相应的TCB ( Thread Control Block,线程控制块),通过TCB对线程进行管理。“内核级线程”就是“从操作系统内核视角看能看到的线程”
 

五、多线程模型

      有些OS把用户级线程和内核支持线程两种方式进行组合,提供了组合方式ULT/KST 线程。在组合方式线程系统中,内核支持多个内核支持线程的建立、调度和管理,同时,也允许用户应用程序建立、调度和管理用户级线程。

5.1 一对一模型

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

优点:当一个线程被阻塞后,别的线程还可以继续执行,并发能力强。多线程可在多核处理机上并行执行。
缺点:一个用户进程会占用多个内核级线程,线程切换由操作系统内核完成,需要切换到核心态,因此线程管理的成本高,开销大。
 

5.2 多对一模型

多个用户级线程映射到一个内核级线程。且一个进程只被分配一个内核级线程。

优点:用户级线程的切换在用户空间即可完成,不需要切换到核心态,线程管理的系统开销小,效率高。
缺点:当一个用户级线程被阻塞后,整个进程都会被阻塞,并发度不高。多个线程不可在多核处理机上并行运行。

操作系统只“看得见”内核级线程,因此只有内核级线程才是处理机分配的单位。

5.3 多对多模型

n用户及线程映射到m个内核级线程(n >= m)。每个用户进程对应m个内核级线程。 



      克服了多对一模型并发度不高的缺点(一个阻塞全体阻塞),又克服了一对一模型中一个用户进程占用太多内核级线程,开销太大的缺点。
可以这么理解:
用户级线程是“代码逻辑”的载体
内核级线程是“运行机会”的载体
内核级线程才是处理机分配的单位。例如:多核CPU环境下,上图这个进程最多能被分配两个核。一段“代码逻辑”只有获得了“运行机会”才能被CPU执行。内核级线程中可以运行任意一个有映射关系的用户级线程代码,只有两个内核级线程中正在运行的代码逻辑都阻塞时,这个进程才会阻塞。
 

六、线程的状态与转换 

      与传统的进程一样,在各线程之间也存在着共享资源和相互合作的制约关系,致使线程在运行时也具有间断性。相应地,线程在运行时也具有下述三种基本状态: (1) 执行状态,表示线程已获得处理机而正在运行; (2) 就绪状态,指线程已具备了各种执行条件,只须再获得CPU便可立即执行; (3) 阻塞状态,指线程在执行中因某事件受阻而处于暂停状态,例如,当一个线程执行从键盘读入数据的系统调用时,该线程就被阻塞。 

 

七、 线程的组织与控制

      如同每个进程有一个进程控制块一样,系统也为每个线程配置了一个线程控制块TCB,将所有用于控制和管理线程的信息记录在线程控制块中。 


八、总结

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/420852.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Tableau 2024.3 快来了,你期待哪些新功能?

时隔不久,Tableau 再次发力,即将推出 2024.3 新版本! 今年 7 月,Tableau 2024.2 的发布为数据分析领域带来了诸多创新。 时隔不久,Tableau 再次发力,即将推出 2024.3 新版本!届时,将…

掌握动态文档生成的艺术:探索Python的docxtpl库

文章目录 掌握动态文档生成的艺术:探索Python的docxtpl库1. 背景介绍2. 库简介3. 安装指南4. 基础函数介绍5. 实际应用场景6. 常见问题及解决方案7. 总结 掌握动态文档生成的艺术:探索Python的docxtpl库 1. 背景介绍 在数据处理和自动化办公领域&#x…

今天讲点简单的:进制1

啊,哈喽,小伙伴们,大家好。我是#Y清墨,今天呐,我要介绍的是二进制。 导语 好久不见,今天来玩些简单的——二进制。 一.初步认识 十进制是逢十进一,那么,顾名思义,二进制…

QXlsx编译静态库-配置为Qt模块

Qt读写Excel–QXlsx编译为静态库-配置为Qt模块🍆 文章目录 Qt读写Excel--QXlsx编译为静态库-配置为Qt模块🍆[toc]1、概述🥔2、准备工作🥕3、配置环境🌽4、加载QXlsx静态库🥒 👉QXlsx使用&#x…

Golang | Leetcode Golang题解之第389题找不同

题目: 题解: func findTheDifference(s, t string) (diff byte) {for i : range s {diff ^ s[i] ^ t[i]}return diff ^ t[len(t)-1] }

编曲术语:各种段落的英文表示 Cubasis和Cubase联合编曲

在编曲中,常见的段落英文表示如下: 前奏(Intro):通常是歌曲开头的部分,用于引入主题,营造氛围。 主歌(Verse):歌曲的主要叙述部分,一般有多段&am…

国庆假期出行必备!西圣PB充电宝!外出旅游出行好搭档!

随着国庆假期的脚步日益临近,大家的心早已飞向了那片期待已久的远方。无论是计划着与家人共赴山水之间,还是与好友相约城市探索,一场说走就走的旅行总是让人心潮澎湃。然而,在享受旅途的欢乐与自由时,手机电量不足的问…

力扣题解2552

大家好,欢迎来到无限大的频道。 今天和大家分享的是2552的题解思路。 题目描述: 统计上升四元组 一个长度为 n 下标从 0 开始的整数数组 nums ,它包含 1 到 n 的所有数字,请你返回上升四元组的数目。 如果一个四元组 (i, j, …

JavaScript高级进阶(二)

JS弹窗 弹窗与语法 警告窗 window.alert()//用于确保用户可以得到某些信息 确认窗 window.confirm()//用于验证是否接受用户操作 提示窗 window.prompt()//用于提示用户在进入页面前输入某个值 <script> //警告窗 alert(欢迎光临); //提示框 var str prompt(是不是…

线程(Thread)

目录 线程&#xff08;Thread&#xff09; 线程的创建方式 实现方式 Runnable和Callable的区别 线程的命名和优先级 线程的六种状态 线程的插队 线程的中断 线程的让出 守护线程 设置线程为守护线程 sleep()和wait()的区别 线程的同步synchronized锁 语法格式 实现…

使用kubeadm部署k8s集群

1、简介 K8s部署主要有两种方式&#xff1a; 1、Kubeadm Kubeadm是一个K8s部署工具&#xff0c;提供kubeadm init和kubeadm join&#xff0c;用于快速部署Kubernetes集群。 2、二进制 从github下载发行版的二进制包&#xff0c;手动部署每个组件&#xff0c;组成Kubernetes集…

828华为云征文|华为云Flexus云服务器X实例之openEuler系统下部署WordPress网站

828华为云征文&#xff5c;华为云Flexus云服务器X实例之openEuler系统下部署wordpress网站 前言一、Flexus云服务器X实例介绍1.1 Flexus云服务器X实例简介1.2 Flexus云服务器X实例特点1.3 Flexus云服务器X实例使用场景 二、WordPress介绍2.1 WordPress简介2.2 WordPress主要特点…

有什么免费好用的ai写作软件?2024帮助你快速进行写作的软件

有什么免费好用的ai写作软件&#xff1f;2024帮助你快速进行写作的软件 AI写作软件如今在提升写作效率、生成灵感、以及帮助完成复杂的写作任务方面表现得越来越出色。以下是五款免费且好用的AI写作软件&#xff0c;它们能够帮助你快速进行写作&#xff0c;无论是博客文章、市…

面试官:为什么 Redis 6.0 之后引入多线程?

大家好&#xff0c;我是大明哥&#xff0c;一个专注「死磕 Java」系列创作的硬核程序员。 回答 Redis 的性能瓶颈从来都不是 CPU&#xff0c;是网络I/O 和内存。 内存好解决&#xff0c;加机器内存和优化数据结构。 网路 I/O 的优化才是大头&#xff0c;因为读写网络的 read…

U盘格式化怎么办?这4款软件可以帮你进行数据恢复。

如果你的U 盘被格式化&#xff0c;里面的数据就会被清除掉了。有备份的话&#xff0c;就不用担心丢失那些重要的数据&#xff1b;如果没有备份&#xff0c;也有办法解决&#xff1b;可以用电脑自带的一些功能恢复&#xff0c;或者是使用专业的恢复软件。如果大家有需求&#xf…

【MTC拾取放置示例】将Connect中的最大目标偏差检查增加到1e-2,实现move to pick/move to place

问题描述 在运行Moveit2使用MTC构建拾取放置示例Pick and Place with MoveIt Task Constructor的时候出现报错 move to pick规划失败 “The computed trajectory is too short to detect jumps in joint-space. Need at least 10 steps, only got 2. Try a lower max_step”…

自带线充电宝哪个牌子质量好性价比高?口碑最好自带线充电宝

在如今这个快节奏的时代&#xff0c;手机等电子设备已经成为我们生活中不可或缺的一部分。然而&#xff0c;电量不足的困扰时常让我们陷入尴尬境地。自带线充电宝的出现&#xff0c;无疑为我们解决了这一难题。它不仅方便携带&#xff0c;无需再额外携带充电线&#xff0c;而且…

iphone16-iphone16pro原壁纸分享

iphone16-iphone16pro原壁纸分享 苹果公司在2024年9月10日的秋季新品发布会上正式推出了iPhone 16系列智能手机。以下是iPhone 16系列的主要特点和更新&#xff1a; 全新A18芯片&#xff1a;iPhone 16系列搭载了苹果最新的A18芯片&#xff0c;这款芯片专为苹果智能&#xff08;…

2024年CCPC网络赛K题题解 —— 取沙子游戏(gym105336K)

比较新的一类博弈题&#xff0c;考虑对因子的处理。题面&#xff1a; 在网络赛以前&#xff0c;我曾经做到过一道类似的题目&#xff1a; Bob和Alice和两堆石头&#xff0c;一堆有s1个&#xff0c;另一堆有s2个&#xff0c;然后Alice先手&#xff0c;每个人每次可以选择一堆石头…

【NVMe SSD寄存器、数据结构】NVMe Controller 重要寄存器、SSD内部跟NVMe相关的重要数据结构解析

前言 NVMe Controller会将一些重要的信息&#xff08;NVMe控制器的能力&#xff0c;状态&#xff0c;Admin SQ, CQ地址等&#xff09;直接放在NVMe寄存器中&#xff0c;另一部分&#xff08;跟SSD比较相关的&#xff09;信息会放置在SSD内部&#xff0c;并最终通过Admin NVMe …