0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

线程是如何靠中断切换的呢

冬至配饺子 来源:天奇工作室 作者:LRC 2022-08-02 18:19 次阅读

上一次的大合集我们从半导体讲到了逻辑门,再从逻辑门讲到了组合逻辑电路和时序逻辑电路,又紧接着介绍了CPU内核的设计体系,最后以CPU的指令集作为结尾,一个CPU已经颇具雏形。

经过11-19章的更新,我们又介绍了线程和进程,处理器的中断和异常、特权模式以及最主要的缓存。我将用更清楚连贯的语言将这些内容重新串讲一次,帮助大家更好地理解,当然这也是大合集的本来初衷。

下面开始。

首先是线程和进程。早期的计算机在一段时间内只能运行一段代码,比如计算导弹轨迹,计算完了出结果就好了。这也是计算机最本来最初级的用法。但是随着计算机不断发展,尤其是人民生活水平的不断提高,计算机这样的用法实在是有些过于枯燥了。比如我想边用计算机听歌的同时打下这段文字,就需要计算机能同时做两件事,于是人们就发明了线程,而线程之间通过少量的必要的沟通可以组合形成一个进程,也就是我们通常意义上的应用程序。比如说音乐播放器中,音乐的播放是一个线程,用户的操作界面是另外一个线程,两个线程合起来构成了音乐播放器。当然,一个应用程序(进程)也可以只有一个线程。每个线程包括系统线程都被划定了一个空间,并且高权限线程(系统线程)能访问低权限线程(应用程序)的空间,低权限线程只能访问属于自己的空间,不然病毒线程将大行其道。所以线程的一个基本属性需要在CPU中被明确记录的是权限等级。

对于计算机系统或者CPU来说,越值得信赖的线程的权限等级是越高的。什么是越值得信赖的线程呢?计算机本身的操作系统肯定是值得信赖的,毕竟如果连操作系统都不能信赖,还有什么值得信赖?不过操作系统虽然值得信赖,但本身肯定多多少少存在一些Bug,不然Windows也不会天天蓝屏了,但是对于CPU来讲,操作系统即使有无心的错误,但肯定不会是有害的错误。

那么权限等级能决定什么呢?能决定这个线程能访问哪些内容。

话说回来,早期的那个计算导弹的程序在现在看来就可以算是一个线程。而具体是如何做到并行处理的呢?看过三体的同学应该都知道三体人是怎么用一颗智子封锁地球科技的,靠的就是智子光速来回穿梭干扰在位于地球各处的高能粒子对撞机。因为智子速度太快了,所以只需要一颗就能封锁整个地球的科技。CPU也是同理,随着CPU性能的提升,它也可以快速来回切换并处理不同的线程,底层都是串行的,但给我们的感觉却是并行的。

当然随着科技的进一步发展,CPU的核心数早已从单核心变成了多核心,甚至在一些服务器里我们还能见到多CPU的主板,所以依靠多个CPU核心,现在也能实现真正意义上的并行,不过线程数总是多于CPU核心数,因此线程的切换即使到了今天也是一直在用的。

那么线程是如何切换的呢?最常见的就是靠中断了。中断顾名思义,做到中间的时候被打断了,有更高优先级的人物需要处理。什么被打断了?当前执行的线程被打断了。被什么打断了?不好说,有可能是定时时钟,有可能是你敲击的键盘或你移动的鼠标,有可能是某一个线程自己发出来的“软中断”。为什么要有中断?就我个人理解,中断是人与电脑进行实时交互的窗口,没有中断就像你没有鼠标和键盘,啥也做不了。但是中断并不是只有人可以用,计算机本身也能用,只要是优先级更高的任务需要介入就可以用。

所以线程是如何靠中断切换的呢?

第一个方法,我称之为被动切换。系统里的计时器会对该线程计时,时间差不多了(大概是5ms左右,看系统设定)就该把CPU让位置出来给另一个线程了。具体过程是,当系统时钟达到设定的时间时,向CPU发送一个中断信号,CPU将现在线程的上下文作为栈保存在内存中,暂时储存起来,同时将pc寄存器跳转到内存中存有中断服务例程的入口处,执行中断服务例程的程序,程序会查找得知中断来源(这一步在高级的CPU上可以用硬件实现从而省略软件查找的过程),进而跳转到系统调度线程,这个线程会根据执行情况将一个新线程调度到CPU上执行,自己则退隐。从而实现线程的切换。

第二个办法,我称之为主动切换。当本线程没事干了,或者说在等另一边的结果,那么这个时候就会执行一个软中断,自觉地把线程让出来(要是不自觉就没办法了),流程和上面一致,只不过中断源不再是时钟了,而是线程本身,称之为软(软件)中断。

还有一种办法不是靠中断切换线程,也可以并行处理的一种技术叫做超线程技术。这个技术是Intel率先提出来的,他们声称增加5%的晶体管数量可以提升20%的性能。

可以理解为如果当前线程没事干,而且这个线程“不自觉退出”,那么硬件直接介入让另外一个线程运行。与上面靠中断的第二种方法不同的是,这种切换是CPU硬件自发的,操控粒度可以更细(前者只能在软件层面判断是否会有空闲情况发生,后者则能在硬件层面监控,硬件发生堵塞情况软件是无法知道的),智能程度会更高,线程切换的过程消耗也会更小。如此一来,CPU可以在本该空等的地方择机执行另外一个线程的指令,实现了时间管理,缩短了两个程序执行的总体时间。

上文中提到的线程切换技术中除了第一种被时钟叫停的以外,基本都是太闲了主动让位或者被让位的。那么为什么会出现线程太闲的情况呢?因为他们在等。等的可能是远方服务器的响应,可能是用户的输入,可能是内存数据的返回……前两种无关性能,解决不了也不用解决,但是等内存可不行,所以介于CPU核心和内存之间的缓存出现了。

缓存读写速度要比内存快,因为缓存采用的是SRAM存储器内建在CPU上,而内存采用的是DRAM。前者可以达到很高的读取速度但是面积占用比较大因此容量上不去,在几M容量就止步了。后者读取速度慢且每次读取后都要刷新电容,但面积占用小,因此容量可以达到好几个G甚至几百几千个G。

那为什么缓存能提高CPU性能呢?程序运行具有一定规律——顺序和反复性,即顺序执行和循环执行。对于顺序执行,可以采取预读策略。即将后面的程序一并读取至缓存中,减少内存读取次数(注意CPU的读指令并没有减少,只是内存响应次数少了)。缓存行是缓存的基本单位,目前主流缓存行大小是64字节因为内存一次读操作是64字节,而64位CPU对数据的读取是8字节即64bit,因此若CPU要读的八字节落入某一缓存行中,该缓存行的内容将会全部从内存中被读取到缓存中,接下来的程序也被这次读写一并带到了缓存中去。对于循环执行,则正是缓存的强项,之前访问过的程序都存储在缓存中,再次读取时,直接可以从缓存而不是从内存中读取,大大提高了运行效率。

缓存又有分为一级缓存、二级缓存等等。他们的速度也有所不同,从一级缓存以后读取速度依次降低。为什么呢?虽然都是采用的SRAM存储器,但是数据检索需要时间,数据存储量大的三级缓存找的时间就比数据存储量小的一级缓存找的时间久。如果把内存比作图书馆的书架,那么缓存就像是CPU面前的一张桌子。给你地址让你去找CPU想要的数据,如果你是在书架上找,你可以很清楚这个数据放在哪一行哪一列,如果恰好你运动速度是光速的话,那么你总能在一个确定的时间内拿到CPU想要的数据。可是缓存就不一样了,书就在你面前,还乱糟糟的,你需要翻阅查看地址是否对应上了。因此桌子越大,你找得也就越慢。

就没有别的办法了吗?当然有。桌子乱可以整理整理嘛。比如规定一下,第一书架的书只能放在桌子上的A区,第二书架放B区……以此类推。这样一来,找的人便会方便很多,放的人也没有什么困难。

举个例子,假设内存可以被划分成四个缓存块(即内存大小是缓存大小的四倍),记为00,01,10,11四块。每个缓存块又可以划分成四个缓存行,记为00,01,10,11四行。结合起来,最上面缓存块的最上面的缓存行就可以写成0000,则这个部分的数据应该存在于缓存中的第一个缓存行的位置即00位置。如果1000号缓存行需要写入,那么就要把0000号缓存行擦除再写入,不能存储在缓存中别的地方即使还有空间存放。


审核编辑:刘清


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 处理器
    +关注

    关注

    68

    文章

    18237

    浏览量

    222015
  • cpu
    cpu
    +关注

    关注

    68

    文章

    10428

    浏览量

    206511
  • 中断
    +关注

    关注

    5

    文章

    884

    浏览量

    41020
  • 计时器
    +关注

    关注

    1

    文章

    395

    浏览量

    32148
收藏 人收藏

    评论

    相关推荐

    求助,是否可以不用pendSV中断做任务切换

    freeRTOS的任务切换我的理解是:通过SysTick中断去触发pendSV中断去做任务切换,因为pendSV中断优先级最低,所以任务
    发表于 04-16 07:59

    基于RTOS的应用进程中的典型线程

    RTOS中的关键因素是最小的中断延迟和最小的线程切换延迟。RTOS的价值在于它的响应速度或可预测性,而不是它在给定时间段内可以执行的工作量。
    发表于 03-05 09:32 115次阅读
    基于RTOS的应用进程中的典型<b class='flag-5'>线程</b>

    利用数字锁相环(DPLL)实现相位增建和无中断切换

    电子发烧友网站提供《利用数字锁相环(DPLL)实现相位增建和无中断切换.pdf》资料免费下载
    发表于 11-24 09:36 0次下载
    利用数字锁相环(DPLL)实现相位增建和无<b class='flag-5'>中断</b><b class='flag-5'>切换</b>

    一个线程模拟单片机程序框架分享

    首先来个demo,该demo是使用电脑开两个线程:一个线程模拟单片机的定时器中断产生时间片轮询个时钟,另一个线程则模拟主函数中一直运行的时间片轮询调度程序。
    发表于 11-19 10:39 372次阅读
    一个<b class='flag-5'>线程</b>模拟单片机程序框架分享

    Linux线程线程与异步编程、协程与异步介绍

    协程不是系统级线程,很多时候协程被称为“轻量级线程”、“微线程”、“纤程(fiber)”等。简单来说可以认为协程是线程里不同的函数,这些函数之间可以相互快速
    的头像 发表于 11-11 11:35 419次阅读
    Linux<b class='flag-5'>线程</b>、<b class='flag-5'>线程</b>与异步编程、协程与异步介绍

    用Freertos在串口中断中释放信号量,线程捕捉不到是为什么?

    用Freertos在串口中断中释放信号量,线程捕捉不到
    发表于 10-15 10:40

    嵌入式进程和线程的区别

    需要进行大量计算的优先使用线程 所谓大量计算,当然就是要耗费很多CPU,切换频繁了,这种情况下线程是最合适的。这种原则最常见的是图像处理、算法处理。
    发表于 09-04 10:05 169次阅读
    嵌入式进程和<b class='flag-5'>线程</b>的区别

    线程池的线程怎么释放

    线程分组看,pool名开头线程占616条,而且waiting状态也是616条,这个点就非常可疑了,我断定就是这个pool开头线程池导致的问题。我们先排查为何这个线程池中会有600+的
    发表于 07-31 10:49 1216次阅读
    <b class='flag-5'>线程</b>池的<b class='flag-5'>线程</b>怎么释放

    Linux中断情景分析

    在一个系统中,中断时常发生,而且线程调度也是由一个硬件定时器时时刻刻发出中断来支撑的。可以说中断就是linux系统的灵魂。
    发表于 06-23 14:22 359次阅读
    Linux<b class='flag-5'>中断</b>情景分析

    核心线程数和最大线程数区别

    核心线程数和最大线程数区别 核心线程数是线程池中一直存在的线程数,不会被回收。最大线程数是
    的头像 发表于 06-01 09:33 6012次阅读

    【RISC-V开发板】并行多线程处理器MC3172开发资料集合

    厦门感芯科技多线程处理器MC3172开发板 ,64线程同步并行运行,各个线程速度可按需配置,硬件级实时响应,无需中断服务程序,无需实时操作系统。RISC-V RV32IMC 指令集,1
    发表于 05-23 11:44

    进程和线程的区别

    每个进程都有独立的代码和数据空间(程序上下文),程序之间的切换会有较大的开销;线程可以看做轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己独立的运行栈和程序计数器(PC),
    的头像 发表于 05-09 11:06 3400次阅读
    进程和<b class='flag-5'>线程</b>的区别

    怎么解决创建多个线程和消息队列失败的问题

    设置的线程栈太大了,就会提示堆内部设置的不够,是不是RT-Thread中其实也是一样的,我应该在哪把数值调大
    发表于 05-05 14:20

    很多变量多线程读写是使用关中断好还是使用互斥进行保护

    会打断当前线程去获取同一个互斥量,由于锁被占,高优先级挂起,低优先级继续执行,释放互斥锁后高优先级执行。这样会有多两次线程切换开销。 2.如果在读写的时候进入中断临界,低优先级读写完后
    发表于 05-05 14:14

    RT-Thread多线程切换最终导致线程创建失败请各位指点一下是什么原因

    我在测试rt-thread 在龙芯2k上线程切换所需的花销,我的思路是创建1000个线程,所创将的线程都存放在全局静态数组中,线程中的内容是
    发表于 04-27 10:49