以操作系统的角度解释线程|进程

1、什么是线程

什么是线程?线程与进程有什么关系?这是一个非常抽象的问题,也是一个特别广的话题,涉及到非常多的知识。


2、任务调度

线程是设么?要理解这个概念,必须先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这就是我们所说的并发,多任务运行过程的示意图如下:


3、进程

我们都知道计算机的核心是CPU,它承担了所有计算任务;而操作系统是计算机的管理者,他负责任务的调度、资源的分配和管理、统领整个计算机硬件;应用程序则是具有某种功能的程序,程序是运行于操作系统之上的。

进程是一个具有独立功能的程序在一个数据集上的一次动态执行的过程,是操作系统进行资源分配和调度的一个独立单位,是应用程序运行的载体。进程是一种抽象的概念,从来没有统一的标准定义。进程一般由程序、数据集合和进程控制块三部分组成,程序用于描述进程要完成的功能,是控制进程执行的指令集;数据集合是程序在执行时所需的数据和工作区;程序控制块(Program Control Block,简称PCB),包含进程的描述信息和控制信息是进程存在的唯一标识。

进程具有的的特征:

(1)动态性:进程是程序的一次执行过程,是临时的,有生命周期的,是动态产生、动态消亡的;

(2)并发性:任何进程都可以同其他进程一起并发执行;

(3)独立性:进程是系统进行资源分配和调度的一个独立单位;

(4)结构性:进程由程序、数据和进程控制块三部分组成;

4、线程

在早期的操作系统中并没有线程的概念,进程是能拥有资源和独立运行的最小单位,也是程序执行的最小单位。任务调度采用的是时间片轮转的抢占调度方式,而进程是任务调度的最小单位,每个进程有各自独立的一块内存,使得各个进程之间内存地址相互隔离。

后来随着计算机的发展,对CPU的要求越来越高,进程之间的切换开销较大,已经无法满足越来越复杂的程序的要求了。于是发明了线程,线程是程序执行中一个单一的顺序控制流程,是程序执行流的最小单元,是处理器调度和分派的基本单位。一个进程可以有一个或多个线程,各个线程之间共享程序的内存空间(也就是所在的进程内存空间)。一个标准的线程由线程ID、当前指令指针(pc)、寄存器和堆栈组成。而进程由内存空间(代码、数据、进程空间、打开的文件)和一个或多个线程组成

5、进程与线程的区别

前面讲了进程与线程,但可能你还觉得迷糊,感觉他们很类似,的确,进程与线程有着千丝万缕的关系,下面就让我们一起来理一理:

(1)线程是程序执行的最小单位,而进程是操作系统分配资源的最小单位;

(2)一个进程由一个或多个线程组成,线程是一个进程中代码 的不同执行路线;

(3)进程之间想独立,但同一个进程下的各个线程之间共享程序的内存空间(包括代码段、数据集、堆等)及一些进程级的资源(如打开文件和信号),某进程内的线程在其它进程不可见;

(4)调度和切换:线程上下文切换比进程上下文切换要快的多。

线程与进程关系的示意图:



总之,线程和进程都是一种抽象的概念,线程是一种比进程更小的抽象,线程和进程都可用于并发。

在早期的操作系统中并没有线程的概念,进程是能拥有资源和独立运行的最小单位,也是程序执行的最小单位。它相当于一个进程里只有一个线程,进程本身就是线程。所以线程有时被称为轻量级进程(Lightweight Process,LWP)。


后来随着计算机的发展,对多个任务之间上下文切换的效率要求越来越高,就抽象出一个更小的概念——线程,一般一个进程会有多个(也可一个)线程。


6、多线程与多核

上面提到的时间片轮转的调度方式说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行,很多操作系统的书都说“同一时间点只有一个任务在执行”。哪有人可能要问双核处理器呢?难道两核不是同时运行吗?

其实“同一时间点只有一个任务在执行”这句话是不准确的,至少它是不全面的。那多核处理器的情况下,线程是怎样执行呢?就需要了解内核线程。

多核处理器是指在一个处理器上集成多个运算核心从而提高技术能力也就是有多个真正并行计算的处理核心,每一个处理核心对应一个内核线程。内核线程(Kernel Thread,KLT)就是直接由操作系统内核支持的线程,这种线程由内核来完成线程切换,内核通过操作调度器对线程进程调度,并负责将线程的任务映射到各个处理器上。一般一个处理核心对应一个内核线程,比如单核处理器对应一个内核线程,双核处理器对应两个内核线程,四核处理器对应四个内核线程。

现在的电脑一般是双核四线程、四核八线程,是采用超线程技术将一个物理处理核心模拟成两个逻辑处理核心,对应两个内核线程,所以在操作系统中看到的CPU数量是实际物理CPU数量的两倍,如果你的电脑是双核四线程,打开“任务管理器/性能”可以看到4个CPU的监视器,四核八线程可以看到8个CPU监视器。


超线程技术就是利用特殊的硬件指令,把一个物理芯片模拟成两个逻辑处理核心,让单个处理器都能使用线程级并行计算,进而兼容多线程操作系统和软件,减少了CPU的闲置时间,提高了CPU的运行效率。这种超线程技术有处理器硬件决定,同时也需要操作系统的支持才能在计算机中表现出来。

程序一般不会直接取使用内核线程,而是去使用内核线程的一直高级接口——轻量级进程(Light Weight Process,LWP),轻量级进程就是我们通常意义上所讲的线程(我们在这成它为用户线程),由于每个轻量级进程都由一个内核线程支持,因此只有先支持内核线程,才能有轻量级进程。用户线程与内核线程的对应关系有三种模型:一对一模型、多对一模型、多对多模型,在这以4个内核线程、3个用户线程为例对三种模式进行说明。

一对一模型:

对于一对一模型来说,一个用户线程就唯一地对应一个内核线程(反过来不一定成立,一个内核线程不一定有对应的用户线程)。这样,如果CPU没有采用超线程技术(如四核四线程的计算机),一个用户线程就唯一地映射到一个物理CPU的线程,线程之间的并发值真正的并发,一对一模型使用户线程具有与内核线程一样的优点,一个线程因某种原因阻塞时其他线程的执行不受影响;此处,一对一模型也可以让多线程程序在多处理器的系统上有更好的表现。但一对一模型也有两个缺点:

(1)许多操作系统限制了内核线程的数量,因此一对一模型会使用户线程的数量受到限制;

(2)许多操作系统内核线程调度时,上下文切换的开销比较大,导致用户线程的执行效率下降。


多对一模型:

多对一模型将多个用户线程映射到一个内核线程上,线程之间的切换由用户态的代码来进行,因此相对一对一模型,多对一模型的线程切换速度要快许多;因此,多对一模型对用户线程的数量几乎无限制,但多对一模型也有两个缺点:

(1)如果其中一个用户线程阻塞,那么其他所有线程都将无法执行,因此此时内核线程也随之阻塞了;

(2)在多处理器系统上,处理器数量的增加对多对一模型的线程性能不会有明显的增加,因此所有的用户线程都映射到一个处理器上了。


3多对多模型:

多对多模型结合了一对一模型和多对一模型的优点,将多个用户线程映射到多个内核线程上,多对多模型的优点有:

(1)一个用户线程的阻塞不会导致所有线程的阻塞,因此此时还有别的内核线程被调度来执行;

(2)多对多模型对用户线程数量没有限制;

(3)在多处理器的操作系统中,多对多模型的线程也能得到一定的性能提升,但提升的幅度不如一对一模型的高度。


7、线程生命周期

当线程的数量小于处理器的数量时,线程的并发是真正的并发,不同的线程运行在不同的处理器上,但当线程的数量大于处理器的数量时,线程的并发会受到一些阻碍,此时并不是真正的并发,因为此时至少有一个处理器会运行多个线程。

在单个处理器运行多个线程时,并发是一种模拟出来的状态。操作系统采用时间片轮转的方式轮流执行每一个线程。现在,几乎所有的现代操作系统采用都是时间片轮转的抢占式调度方式,如我们熟悉的Unix、Linux、Windows及Mac OS等流行的操作系统。我们知道线程是程序执行的最小单位,也是任务执行的最小单位,在早期只有进程的操作系统中,进程有五种状态,创建、就行、运行、阻塞、退出。早期的进程相当于现在只有单个线程进程,那么现在的多线程也有五种状态,现在的多线程的生命周期与早期进程的生命周期类似。


进程在运行过程中有三种状态:就绪、运行、阻塞,创建和退出状态描述的是进程的创建过程和退出过程。

(1)创建:进程正在创建,还不能运行,操作系统在创建进程时要进行的工作包括分配和建立进程控制块表项、建立资源表格并分配资源、加载程序并建立地址空间;

(2)就绪:时间片已用完,此线程被强制暂停,等待下一个属于他的时间片到来;

(3)运行:此线程正在执行,正在占用时间片;

(4)阻塞:也叫等待状态,等待某一事件(如IO或另一个线程)执行完;

(5)退出:进程已结束,所以也称结束状态,释放操作系统分配的资源。


线程声明周期:



阅读更多
个人分类: 线程|进程
上一篇spring常见问题
下一篇线程优先级|线程安全
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭