考研408《操作系统》复习笔记,第七章《线程》

参考资料

s​​​​​​​c​​​​​​​2.1_6_线程的实现方式和多线程模型_哔哩哔哩_bilibili

多线程编程:一次性搞懂线程同步机制_哔哩哔哩_bilibili

【操作系统】进程和线程的区别_哔哩哔哩_bilibili

一、线程是啥

在前后端开发里我们就经常遇到线程,现在操作系统也遇到了,但是线程到底是什么?这里就先解释一下

1、理论理念

所谓线程,简单理解就是一个进程里【执行代码语句的顺序】

专业的说法是:线程是进程里最基本的执行单位 ,是CPU调度的最小单位

通俗可以理解成一条道路,执行一条代码就是通过一辆汽车,单线程就是只有一条路,多线程就是有多条路;

那么如果只有一条路,是不是只能一辆车跟着一辆车按顺序通过?这就是单线程

那么如果单线程里前面有一辆车故障堵住了,后面的车不就得干等?如果是多条路,那么有些车就可以到别的路上,不用在原来一条路等前面的车,这就是多线程

2、代码理解

我将用Python和JAVA两种语言的示例代码进行解释:

【Python】的多线程

先看单进程情况,单进程下,主函数依次一条一条代码从上往下按顺序执行

用【threading.Thread( )】函数之后可以创建一个多线程,并指定这个线程执行什么事情,通过 "线程.start()" 函数让其启动

那么这里创建了第二个线程 "t1",并指定执行worker这个函数,于是可以看到主函数没有去等worker函数的逻辑执行完直接就执行到底了,然后t1线程还在执行worker剩下的内容任务

这是因为相当于开辟了两条 "道路",主函数单独走自己的路,t1进程也单独走自己的路,互不影响,因此主函数直接走到底了,然后t1也同时走自己的路一路到底,不存在什么先后顺序了

下面这个例子直接创建"t1"、 "t2"两个线程,现在主函数、t1、t2相当于3条路,各自都同时往后执行,互不影响,所以能看到有时t1先输出结果、有时t2先输出结果,但是没有具体谁先谁后,因为他两同时进行的

【JAVA】示例多线程

单线程情况下,从上到下按顺序执行每一行代码

那么用【new Thread()】可以创建一个线程对象,在这个对象里可以写你要执行的内容,然后再用 "线程.start()" 的方法就可以启动这个线程

那么可以看到多线程的情况,每一次执行,输出的结果都不一样,是因为这三个进程是同时进行的,并没有明确的先后顺序之分

3、实际应用理解

但是计数看了这么多例子,可能还是有人不理解究竟为什么说线程是:进程里最基本的执行单位 ,是CPU调度的最小单位

首先,传统的计算机里,系统里的每一个程序都只能串行运行,在运行QQ时想运行音乐软件,就得停掉QQ再运行音乐程序;但是有了【进程】之后,就可以边听歌边用QQ了

但是对于一个进程里,比如QQ这个例子,我们平时可以用QQ同时看视频、文字聊天、传送文件......,那么这些事明显不是在这个进程里按顺序执行的

传统的进程内,就是CPU分时地对各个进程进行按顺序的串行执行每一行代码

因此为了处理 "高并发运行 ",现在的进程里都引入了【线程】,CPU不再是只执行进程,而是通过特定的算法分别执行各个线程

可以把【线程】理解为 "轻量级的进程",他才是CPU最基本的执行单元CPU调度的最小单位程序执行流的最小单位进程里最基本的执行单位

引入了线程之后,不仅进程之间可以并发执行,线程之间也可以并发运行

注意,引入【线程】之后,进程不再是CPU调度执行的最小单位!

而只是除了CPU之外的系统资源的分配最小单元(也就是打印机、音频播放器、摄像头......等等I/O设备的资源,是给进程的,而不是给线程的)

二、进程、线程、并发、并行这些关系

那么本人在学到这一章隐约就想起了两个知识点:

  • 1、我在第一章讲过的【并发】和【并行】
  • 2、我上一章讲的【进程】

知识点回顾:

1、【并发】和【并行】概念

2、还没引入线程的传统【进程】运行机制

那么引入了【线程】概念之后,就方便理解为什么单核CPU各个程序的并发运行,多核CPU是并行运行了

首先我们把进程比作各个正在生产产品的工厂,然后线程是里面工作的机器人,CPU是一个超大型发电机,【单核CPU就是只有一条充电线的发电机、 多核就是有多条充电线的发电机】

传统的进程模式下,CPU执行调度的单位是进程,所以只能串行的分时的执行一个一个进程,但是引入了线程之后,【线程】才是CPU调度的单位了,所以即使单核CPU也能够分时并发地执行各个进程里的线程(只不过每次同一时刻还是只能执行一条线程,所以是并发

但是如果是多核CPU,那么他就有能力同时执行多个进程里的多个线程了,那想一下多个 "机器人" 同时充电工作,不就实现了并行了吗

三、线程的实现方式

1、线程库

前面第一大点我提过,python、java都有他们各自在代码里创建线程的方式,那么调用这些方法或者对象的根源,是python、java等编程语言开发者自己写好了一套【线程库】

例如Python

2、两种实现方式

1)用户级线程(ULT, user level thread)

就是 "从用户视角能看到的线程",操作系统看不到线程

这就是基于传统进程实现的,操作系统只调度进程,所以所谓的 "线程" 只是程序员自己调用自己写的 "线程库API" 来实现,不需要操作系统来介入,所以也自然不需要CPU切换用户态、内核态

这样虽然可以避免CPU频繁变换状态,但是并不是真正意义的多线程,因为假设现在有多核CPU,但是由于操作系统只看得到进程,所以CPU还是只能分别运行一个进程而已,而不是真的同时执行多个进程的各个线程。

而且假设一个进程的某一个线程堵塞了,整个进程就堵塞了,影响别的线程正常工作.....

2)内核级线程(KLT, kernel level thread)

就是操作系统来调度操作线程

这就是引入了线程的进程,CPU之间调度运行线程,那就需要操作系统来介入管理,那也自然要由CPU从用户态切换到内核态

然后操作系统会为每个内核级线程创建各自的数据结构------------ "线程控制块"(TCB),操作系统通过对TCB管理来管理线程

虽然要CPU频繁变态,但是不会因为一个线程阻塞而影响别的线程工作;

而且是真正意义上的并发运行多线程,多线程也真正可以在多核CPU上并行运行

3)当然还有组合他两的方式

。。。。。。没啥说的,知道有就行

3、多线程模型

那么对于支持上面第2种的内核级线程的系统,根据【用户级线程】和【内核级线程】的映射关系,又可以分成这么几种模型

1)一对一

2)多对一

3)多对多

四、线程的状态与转换

和进程一样,线程也有自己的几种状态,那么这里的知识点因为大量跟进程重复,所以用进程的思维去理解即可

线程就关注【就绪】【运行】【阻塞】这三个状态,那其实什么时候用什么状态跟进程是一个道理的,所以就不多解释了,只不过我们这里不关心【创建态】和【终止态】

然后关于操作系统如何控制管理线程,也跟进程的原理一样:

进程的一些信息、id标识、状态都被记录在一个数据结构------PCB中,操作系统创建这么一个数据结构来方便管理每一个进程

而线程也一样,现在引入了线程,那么操作系统工作的重心就换成线程了,因此每个线程创建都会对应创建一个数据结构------【TCB】用来存储这个线程的信息

相关推荐
E___V___E1 小时前
MySQL数据库入门到大蛇尚硅谷宋红康老师笔记 高级篇 part 2
数据库·笔记·mysql
爱学习的小王!5 小时前
nvm安装、管理node多版本以及配置环境变量【保姆级教程】
经验分享·笔记·node.js·vue
陈志化5 小时前
JMeter----笔记
笔记·jmeter
qq_437896435 小时前
动态内存分配算法对比:最先适应、最优适应、最坏适应与邻近适应
操作系统
HollowKnightZ5 小时前
论文阅读笔记:Gated CRF Loss for Weakly Supervised Semantic Image Segmentation
论文阅读·笔记
别说我什么都不会5 小时前
鸿蒙轻内核M核源码分析系列十一 (2)信号量Semaphore
操作系统·harmonyos
xzal126 小时前
青少年编程都有哪些比赛可以参加
笔记·青少年编程
StickToForever7 小时前
第4章 信息系统架构(二)
经验分享·笔记·学习·职场和发展
阿噜噜小栈7 小时前
Cursor 无限续杯
经验分享·笔记
omage9 小时前
cornerstone3D学习笔记-MPR
笔记·学习·vtk·dicom·mpr