多线程是怎样发展来的

434 阅读8分钟

  初入染缸,不知深浅,记少年长成。

前言

  本文摘要: “为什么会有多线程”、“多线程是什么”。

  若有偏颇之处,欢迎指正。同时,若文章侵犯了你的权益,请及时与我联系:bycqgEmail@163.com

一、为什么会有多线程

  为什么会有多线程?多线程的形成,经由单任务时代,到多进程时代,再到多线程时代,其发展的最根本动力在于CPU执行速度、IO操作速度(包含内存IO、磁盘IO等)之间的不平衡而所造成的CPU资源浪费。下面,介绍一下这三个时代。

1、单任务时代

  在单任务时代,CPU执行的程序指令都是事先写在卡片上的,之后通过读卡机进行IO操作读入内存。这时期的计算机同一时刻只能执行一个任务,即IO读入写出时就不能进行CPU计算,CPU计算时就不能进行IO读入写出。

  而计算机执行流程,首先要人工将卡片装载,再由读卡机对卡片进行IO读入,再由计算机CPU对读入的指令进行执行。因为计算机CPU的执行速度远超于指令的读入、结果的输出,所以这就导致在人工装载、IO读入写出这两个步骤上白白闲置了CPU。

  再后来,为了提高效率,就对指令输入进行了优化,由对一个卡片写入一个程序指令衍变成对一个磁带写入多个程序指令,那么第一个步骤“人工装载”装载一次就足够计算机长时间读入,不用一直更换卡片,从而省去了更换卡片浪费的时间。

2、多进程时代

  单任务时代由于没有对内存空间进行概念上的划分,所以磁带将程序指令通过IO读入相应内存空间时,CPU处于闲置状态,只有IO读入完毕后CPU开始执行内存空间中指令,执行完再继续等待下一个程序指令的读入,以此往复。

  此时的内存空间被认知为同一时刻只为一个应用程序服务,内存是没有进行概念上的划分的,而多进程时代为了提高效率,就将内存划分为独立存在的一个个内存空间,每一个内存空间对应一个应用程序,概念上对应为一个进程。

  进程空间可以同时通过读卡机读入程序指令,那么CPU就可以在某个内存空间IO读入程序指令的时候转去执行另一个已经读入程序指令的内存空间中的指令,即把CPU时间片分配给该进程。这就是充分利用第二个步骤“IO读入”时期的时间。

2.1、IO操作为什么会导致CPU闲置?

  这是因为进程需要某个资源时,会由CPU对DMA(Direct Memory Access)发出请求,然后由DMA去处理资源载入,处理完成之后通过中断通知CPU即可。CPU发出请求占用时间很短,大部分时间都是CPU在等待资源的载入。

3、多线程时代

  多进程时代中CPU基于进程进行调度提高了CPU的利用率,但依然存在缺陷。多进程时代系统调度的最小单元是进程,这就导致一个进程在分配到的时间片内执行一个操作时,如果该操作导致进程阻塞(比如IO操作),会致使进程挂起,引出以下问题:切换进程消耗资源、该IO操作后面的一些不依赖于该IO操作的操作无法执行。

  现在,引入多线程概念系统调度的最小单元就变成了线程,简单来说每一个操作都可以交由一个线程来处理。那么前面提到的问题就得以解决,当执行IO操作时,CPU会转去执行进程中的另一个操作,而不会挂起进程,从而免去了切换进程这一个很浪费系统资源的操作。

  多线程这个概念的产生,使得一个进程中的一个IO操作后面的、不依赖于该IO操作的操作可以被CPU执行,在避免了进程切换的同时还加快了本进程的整体执行进度,本进程的整体执行进度的提高意味着进程之间的切换次数就会减少。

  多线程这个概念的产生是一个很大的进步,毕竟如果没有多线程,那么用户打开一个word文件,当需要进行IO操作的时候,计算机就要卡在那里什么也做不了。而有了多线程,计算机就可以将等待IO操作完成后的应答的工作交由线程A去处理,然后让CPU转向线程B去执行例如“打开word窗口”等不依赖于该IO操作的程序指令,这大大优化了用户体验。

3.1、减少进程间的切换次数有什么好处?

  可以加快了当前进程的执行进度。要知道,进程切换相较于线程切换是十分消耗资源的。因为进程是系统进行资源调度与分配的基本单元,每个进程都享有私有的地址空间和独立的资源配置,而每个线程则是每个进程众多顺序执行流中的一个,这些顺序执行流是能够共享进程的某块地址空间的。因为进程使用的是不同的资源,所以切换个进程就会导致所有cache失效,而线程之间是可以共享同一个进程的同一份资源的,cache的命中是可能的。

4、多核CPU时代

  不断地发展使得CPU利用率不断提升,但是CPU利用率的提升总归有瓶颈。随着需要处理的线程的数目的增多,单核CPU已经无法及时处理众多线程,所以引入多核CPU,真正意义上实现了多任务同时执行。

4.1、并发与并行

  并发是通过单核CPU超高的执行速度使得多个顺序执行的指令(或线程、或进程)的执行过程看起来像是同时执行的一样,在单核CPU时代实现的都是并发。

  举个例子,在12M晶振的51单片机中每条指令执行所花费的时间为1us,现在有三条指令需要CPU执行,那么三条指令的顺序执行过程(总共花费3us)在人的脑海中的感觉是不是像是在同时进行的?答案是肯定的。

  并行是通过多核CPU中的多个处理器来实现真正意义上的同时执行。同样面对上面那种情况,假如当前计算机是三核的,那么一个处理器分配一条指令的执行任务,三个处理器同时执行,总共花费1us,这才是真正意义上的同时执行。

二、多线程是什么

  线程、进程都是抽象出来的概念,并且是在对进程进行更加细粒度的划分后抽象出的线程这个概念,它们本质上都是为了提高CPU的利用率而衍生出来的。线程在看作一种概念的同时也可以看作是一种单位,是系统进行调度的最小单元,当系统在多个线程之间调度分配也就形成了多线程。所以多线程就是一种抽象的概念,对应到实际中就是进程中的多个顺序执行流。

1、程序、进程、线程三者之间的联系是什么?

(1)、程序:程序就是通过程序指令和程序数据完成某一些逻辑功能的操作。一个程序包含程序指令、程序数据,程序是静态的,它存放在外存之中,当它被调进内存之中并被CPU执行时就形成了进程。

(2)、进程:进程就是运行起来的程序,它是系统进行资源调度与分配的基本单位,它拥有私有的地址空间和独立的资源配置,也就是说多个软件同时被调进内存之中交由CPU执行时,相互之间是不可见的。

(3)、线程:线程就是为了提高CPU的利用率而从进程中抽象出来的概念,它是系统调度的最小单元,每一个进程中都包含了多个顺序执行流,每一个顺序执行流就是一个线程。

后记

  有条件的老板可以捧个钱~我呸,有条件的老板可以点个赞,转发只需标注出处即可。

  我是半夜唱晴歌,如果文章对你有帮助,欢迎关注公众号「 bycqg 」,谢谢各位老板的支持。