编程思想之多线程与多进程(1)——以操做系统的角度述说线程与进程

原文:http://blog.csdn.net/luoweifu/article/details/46595285 
做者:luoweifu 
转载请标名出处



什么是线程

什么是线程?线程与进程与有什么关系?这是一个很是抽象的问题,也是一个特别广的话题,涉及到很是多的知识。我不能确保能把它讲的话,也不能确保讲的内容所有都正确。即便这样,我也但愿尽量地把他讲通俗一点,讲的明白一点,由于这是个一直困扰我好久的,扑朔迷离的知识领域,但愿经过个人理解揭开它一层一层神秘的面纱。正则表达式

 

任务调度

线程是什么?要理解这个概念,需要先了解一下操做系统的一些相关概念。大部分操做系统(WindowsLinux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每一个任务轮流执行。任务执行的一小段时间叫作时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每一个任务都能获得执行,因为CPU的执行效率很是高,时间片很是短,在各个任务之间快速地切换,给人的感受就是多个任务在“同时进行”,这也就是咱们所说的并发(别以为并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)。多任务运行过程的示意图以下:chrome


图 1操做系统中的任务调度编程

 

 

进程

咱们都知道计算机的核心是CPU,它承担了全部的计算任务;而操做系统是计算机的管理者,它负责任务的调度、资源的分配和管理,统领整个计算机硬件;应用程序侧是具备某种功能的程序,程序是运行于操做系统之上的。浏览器

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

进程具备的特征:多线程

动态性:进程是程序的一次执行过程,是临时的,有生命期的,是动态产生,动态消亡的;并发

并发性:任何进程均可以同其余进程一块儿并发执行;app

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

结构性:进程由程序、数据和进程控制块三部分组成。性能

 

线程

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

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

 

 

进程与线程的区别

前面讲了进程与线程,但可能你还以为迷糊,感受他们很相似。的确,进程与线程有着千丝万缕的关系,下面就让咱们一块儿来理一理:

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

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

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

4.调度和切换:线程上下文切换比进程上下文切换要快得多。

 

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


图 2进程与线程的资源共享关系

 


图 3:单线程与多线程的关系

 

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

 

在早期的操做系统中并无线程的概念,进程是能拥有资源和独立运行的最小单位,也是程序执行的最小单位。它至关于一个进程里只有一个线程,进程自己就是线程。因此线程有时被称为轻量级进程(Lightweight ProcessLWP)。


图 4早期的操做系统只有进程,没有线程

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


图 5:线程的出现,使得一个进程能够有多个线程

 

多线程与多核

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

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

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

如今的电脑通常是双核四线程、四核八线程,是采用超线程技术将一个物理处理核心模拟成两个逻辑处理核心,对应两个内核线程,因此在操做系统中看到的CPU数量是实际物理CPU数量的两倍,如你的电脑是双核四线程,打开“任务管理器\性能”能够看到4CPU的监视器,四核八线程能够看到8CPU的监视器。

 

图 6:双核四线程在Windows8下查看的结果

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

 

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

一对一模型

对于一对一模型来讲,一个用户线程就惟一地对应一个内核线程(反过来不必定成立,一个内核线程不必定有对应的用户线程)。这样,若是CPU没有采用超线程技术(如四核四线程的计算机),一个用户线程就惟一地映射到一个物理CPU的线程,线程之间的并发是真正的并发。一对一模型使用户线程具备与内核线程同样的优势,一个线程因某种缘由阻塞时其余线程的执行不受影响;此处,一对一模型也可让多线程程序在多处理器的系统上有更好的表现。

但一对一模型也有两个缺点:1.许多操做系统限制了内核线程的数量,所以一对一模型会使用户线程的数量受到限制;2.许多操做系统内核线程调度时,上下文切换的开销较大,致使用户线程的执行效率降低。

 

 

图 7:一对一模型

 

 

多对一模型

多对一模型将多个用户线程映射到一个内核线程上,线程之间的切换由用户态的代码来进行,所以相对一对一模型,多对一模型的线程切换速度要快许多;此外,多对一模型对用户线程的数量几乎无限制。但多对一模型也有两个缺点:1.若是其中一个用户线程阻塞,那么其它全部线程都将没法执行,由于此时内核线程也随之阻塞了;2.在多处理器系统上,处理器数量的增长对多对一模型的线程性能不会有明显的增长,由于全部的用户线程都映射到一个处理器上了。

 

图 8:多对一模型

 

多对多模型

多对多模型结合了一对一模型和多对一模型的优势,将多个用户线程映射到多个内核线程上。多对多模型的优势有:1.一个用户线程的阻塞不会致使全部线程的阻塞,由于此时还有别的内核线程被调度来执行;2.多对多模型对用户线程的数量没有限制;3.在多处理器的操做系统中,多对多模型的线程也能获得必定的性能提高,但提高的幅度不如一对一模型的高。

在如今流行的操做系统中,大都采用多对多的模型。

 

图 9:多对多模型

 

 

查看进程与线程

一个应用程序多是多线程的,也多是多进程的,如何查看呢?在Windows下咱们只须打开任务管理器就能查看一个应用程序的进程和线程数。按“Ctrl+Alt+Del”或右键快捷工具栏打开任务管理器。

查看进程数和线程数:

 

图 10:查看线程数和进程数

在“进程”选项卡下,咱们能够看到一个应用程序包含的线程数。若是一个应用程序有多个进程,咱们能看到每个进程,如在上图中,Googlechrome浏览器就有多个进程。同时,若是打开了一个应用程序的多个实例也会有多个进程,如上图中我打开了两个cmd窗口,就有两个cmd进程。若是看不到线程数这一列,能够在点击“查看\选择列”菜单,增长监听的列。

 

查看CPU和内存的使用率:

在性能选项卡中,咱们能够查看CPU和内存的使用率,根据CPU使用记录的监视器的个数还能看出逻辑处理核心的个数,如个人双核四线程的计算机就有四个监视器。

 

图 11:查看CPU和内存的使用率

 

 

线程的生命周期

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

在单个处理器运行多个线程时,并发是一种模拟出来的状态。操做系统采用时间片轮转的方式轮流执行每个线程。如今,几乎全部的现代操做系统采用的都是时间片轮转的抢占式调度方式,如咱们熟悉的UnixLinuxWindowsMac OS X等流行的操做系统。

咱们知道线程是程序执行的最小单位,也是任务执行的最小单位。在早期只有进程的操做系统中,进程有五种状态,建立、就绪、运行、阻塞(等待)、退出。早期的进程至关于如今的只有单个线程的进程,那么如今的多线程也有五种状态,如今的多线程的生命周期与早期进程的生命周期相似。

 

图 12:早期进程的生命周期


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

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

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

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

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

退出:进程已结束,因此也称结束状态,释放操做系统分配的资源。

 

图 13:线程的生命周期

 

建立:一个新的线程被建立,等待该线程被调用执行;

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

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

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

退出:一个线程完成任务或者其余终止条件发生,该线程终止进入退出状态,退出状态释放该线程所分配的资源。


线程和进程相关文章:

编程思想之多线程与多进程(2)——线程优先级与线程安全

编程思想之多线程与多进程(3)——Java中的多线程

编程思想之多线程与多进程(4)——C++中的多线程


原文:http://blog.csdn.net/luoweifu/article/details/46595285 
做者:luoweifu 
转载请标名出处


========================编程思想系列文章回顾========================

编程思想之消息机制

编程思想之日志记录

编程思想之异常处理

编程思想之正则表达式

编程思想之迭代器

编程思想之递归

编程思想之回调




关注【SunLogging】 
这里写图片描述  长按或扫码二维码,在手机端阅读更多内容