考研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】用来存储这个线程的信息

相关推荐
西电研梦2 小时前
利好消息!!西电今年考研可能报考人数跌破1.5万??
考研·研究生·西安电子科技大学·26考研
Yawesh_best5 小时前
告别系统壁垒!WSL+cpolar 让跨平台开发效率翻倍
运维·服务器·数据库·笔记·web安全
vx_dmxq2116 小时前
【PHP考研互助系统】(免费领源码+演示录像)|可做计算机毕设Java、Python、PHP、小程序APP、C#、爬虫大数据、单片机、文案
java·spring boot·mysql·考研·微信小程序·小程序·php
Ccjf酷儿7 小时前
操作系统 蒋炎岩 3.硬件视角的操作系统
笔记
习习.y8 小时前
python笔记梳理以及一些题目整理
开发语言·笔记·python
在逃热干面8 小时前
(笔记)自定义 systemd 服务
笔记
DKPT10 小时前
ZGC和G1收集器相比哪个更好?
java·jvm·笔记·学习·spring
QT 小鲜肉11 小时前
【孙子兵法之上篇】001. 孙子兵法·计篇
笔记·读书·孙子兵法
星轨初途12 小时前
数据结构排序算法详解(5)——非比较函数:计数排序(鸽巢原理)及排序算法复杂度和稳定性分析
c语言·开发语言·数据结构·经验分享·笔记·算法·排序算法
QT 小鲜肉12 小时前
【孙子兵法之上篇】001. 孙子兵法·计篇深度解析与现代应用
笔记·读书·孙子兵法