以操作系统的角度述说线程与进程
Posted 心之所向,素履以往
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了以操作系统的角度述说线程与进程相关的知识,希望对你有一定的参考价值。
引言
面试官经常会问到线程与进程的区别,大多数人的回答都仅限于课本上的那几句定义,比如:
1、定义方面:进程是程序在某个数据集合上的一次运行活动;线程是进程中的一个执行路径。
2、角色方面:在支持线程机制的系统中,进程是系统资源分配的单位,线程是系统调度的单位。
3、资源共享方面:进程之间不能共享资源,而线程共享所在进程的地址空间和其它资源。同时线程还有自己的栈、程序计数器、寄存器。
4、独立性方面:进程有自己独立的地址空间,而线程没有,线程必须依赖于进程而存在。
一、CPU调度
大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)。多任务运行过程的示意图如下:
图 1:操作系统中的任务调度
二、进程的实现
为了实现进程模型,操作系统维护着一张表格(一个结构数组),称为进程表。每个进程占用一个进程表项(PCB),该表项包含了进程状态的重要信息。包括程序计数器,堆栈指针,内存分配状况,打开文件状况,账号和调度信息,以及从运行状态,切换到就绪状态或者阻塞状态必须保存的信息,这样在重新获得CPU时间片能够继续执行,好像从未中断过一样。下图展示了进程表项的关键字段。
图2:进程表项
三、线程的实现
进程之间的切换开销较大,已经无法满足越来越复杂的程序的要求了。于是就发明了线程,线程是程序执行中一个单一的顺序控制流程,是程序执行流的最小单元,是处理器调度和分派的基本单位。一个进程可以有一个或多个线程,各个线程之间共享程序的内存空间(也就是所在进程的内存空间)。一个标准的线程由线程ID、当前指令指针(PC)、寄存器和堆栈组成。而进程由内存空间(代码、数据、进程空间、打开的文件)和一个或多个线程组成。
图3:线程内容
四、进线程的区别
此时就可以回到引言部分所说内容了,
1、定义方面:进程是程序在某个数据集合上的一次运行活动;线程是进程中的一个执行路径。
2、角色方面:在支持线程机制的系统中,进程是系统资源分配的单位,线程是系统调度的单位。
3、资源共享方面:进程之间不能共享资源,而线程共享所在进程的地址空间和其它资源。同时线程还有自己的栈、程序计数器、寄存器。
4、独立性方面:进程有自己独立的地址空间,而线程没有,线程必须依赖于进程而存在。
线程与进程关系的示意图:
图4:进程线程关系
五、多线程与多核
上面提到的时间片轮转的调度方式说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。很多操作系统的书都说“同一时间点只有一个任务在执行”。那有人可能就要问双核处理器呢?难道两个核不是同时运行吗?
其实“同一时间点只有一个任务在执行”这句话是不准确的,至少它是不全面的。那多核处理器的情况下,线程是怎样执行呢?这就需要了解内核线程。
多核(心)处理器是指在一个处理器上集成多个运算核心从而提高计算能力,也就是有多个真正并行计算的处理核心,每一个处理核心对应一个内核线程。内核线程(Kernel Thread, KT)就是直接由操作系统内核支持的线程,这种线程由内核来完成线程切换,内核通过操作调度器对线程进行调度,并负责将线程的任务映射到各个处理器上。一般一个处理核心对应一个内核线程,比如单核处理器对应一个内核线程,双核处理器对应两个内核线程,四核处理器对应四个内核线程。
现在的电脑一般是双核四线程、四核八线程,是采用超线程技术将一个物理处理核心模拟成两个逻辑处理核心,对应两个内核线程,所以在操作系统中看到的CPU数量是实际物理CPU数量的两倍,如你的电脑是双核四线程,打开“任务管理器\\性能”可以看到4个CPU的监视器,四核八线程可以看到8个CPU的监视器。
图5:超线程cpu
超线程技术就是利用特殊的硬件指令,把一个物理芯片模拟成两个逻辑处理核心,让单个处理器都能使用线程级并行计算,进而兼容多线程操作系统和软件,减少了CPU的闲置时间,提高的CPU的运行效率。这种超线程技术(如双核四线程)由处理器硬件的决定,同时也需要操作系统的支持才能在计算机中表现出来。
程序一般不会直接去使用内核线程,而是去使用内核线程的一种高级接口——轻量级进程(Light Weight Process,LWP),轻量级进程就是我们通常意义上所讲的线程(我们在这称它为用户线程),由于每个轻量级进程都由一个内核线程支持,因此只有先支持内核线程,才能有轻量级进程。用户线程与内核线程的对应关系有三种模型:一对一模型、多对一模型、多对多模型,在这以4个内核线程、3个用户线程为例对三种模型进行说明。
一对一模型
对于一对一模型来说,一个用户线程就唯一地对应一个内核线程(反过来不一定成立,一个内核线程不一定有对应的用户线程)。这样,如果CPU没有采用超线程技术(如四核四线程的计算机),一个用户线程就唯一地映射到一个物理CPU的线程,线程之间的并发是真正的并发。一对一模型使用户线程具有与内核线程一样的优点,一个线程因某种原因阻塞时其他线程的执行不受影响;此处,一对一模型也可以让多线程程序在多处理器的系统上有更好的表现。
但一对一模型也有两个缺点:1.许多操作系统限制了内核线程的数量,因此一对一模型会使用户线程的数量受到限制;2.许多操作系统内核线程调度时,上下文切换的开销较大,导致用户线程的执行效率下降。
图 6:一对一模型
多对一模型
多对一模型将多个用户线程映射到一个内核线程上,线程之间的切换由用户态的代码来进行,因此相对一对一模型,多对一模型的线程切换速度要快许多;此外,多对一模型对用户线程的数量几乎无限制。但多对一模型也有两个缺点:1.如果其中一个用户线程阻塞,那么其它所有线程都将无法执行,因为此时内核线程也随之阻塞了;2.在多处理器系统上,处理器数量的增加对多对一模型的线程性能不会有明显的增加,因为所有的用户线程都映射到一个处理器上了。
图 7:多对一模型
多对多模型
多对多模型结合了一对一模型和多对一模型的优点,将多个用户线程映射到多个内核线程上。多对多模型的优点有:1.一个用户线程的阻塞不会导致所有线程的阻塞,因为此时还有别的内核线程被调度来执行;2.多对多模型对用户线程的数量没有限制;3.在多处理器的操作系统中,多对多模型的线程也能得到一定的性能提升,但提升的幅度不如一对一模型的高。
在现在流行的操作系统中,大都采用多对多的模型。
图 8:多对多模型
以上是关于以操作系统的角度述说线程与进程的主要内容,如果未能解决你的问题,请参考以下文章