线程与进程的比较
算法
概述:多线程
进程是具备必定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位.并发
线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程本身基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),可是它可与同属一个进程的其余的线程共享进程所拥有的所有资源.spa
一个线程能够建立和撤销另外一个线程;同一个进程中的多个线程之间能够并发执行.操作系统
相对进程而言,线程是一个更加接近于执行体的概念,它能够与同进程中的其余线程共享数据,但拥有本身的栈空间,拥有独立的执行序列。线程
在串行程序基础上引入线程和进程是为了提升程序的并发度,从而提升程序运行效率和响应时间。指针
区别:对象
进 程和线程的主要差异在于它们是不一样的操做系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个 进程中的不一样执行路径。线程有本身的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,因此多进程的程序要比多线程的程序 健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行而且又要共享某些变量的并发操做,只能用线程,不能用进程。进程
1) 简而言之,一个程序至少有一个进程,一个进程至少有一个线程. 事件
2) 线程的划分尺度小于进程,使得多线程程序的并发性高。
3) 另外,进程在执行过程当中拥有独立的内存单元,而多个线程共享内存,从而极大地提升了程序的运行效率。
4) 线程在执行过程当中与进程仍是有区别的。每一个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。可是线程不可以独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
5) 从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分能够同时执行。但操做系统并无将多个线程看作多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。
优缺点:
线程和进程在使用上各有优缺点:线程执行开销小,但不利于资源的管理和保护;而进程正相反。同时,线程适合于在SMP机器上运行,而进程则能够跨机器迁移。
多进程,多线程
概述:
进程就是一个程序运行的时候被CPU抽象出来的,一个程序运行后被抽象为一个进程,可是线程是从一个进程里面分割出来的,因为CPU处理进程的时候是采用时间片轮转的方式,因此要把一个大个进程给分割成多个线程,例如:网际快车中文件分红100部分 10个线程 文件就被分红了10份来同时下载 1-10 占一个线程 11-20占一个线程,依次类推,线程越多,文件就被分的越多,同时下载 固然速度也就越快
进程是程序在计算机上的一次执行活动。当 你运行一个程序,你就启动了一个进程。显然,程序只是一组指令的有序集合,它自己没有任何运行的含义,只是一个静态实体。而进程则不一样,它是程序在某个数 据集上的执行,是一个动态实体。它因建立而产生,因调度而运行,因等待资源或事件而被处于等待状态,因完成任务而被撤消,反映了一个程序在必定的数据集上 运行的所有动态过程。进程是操做系统分配资源的单位。在Windows下,进程又被细化为线程,也就是一个进程下有多个能独立运行的更小的单位。线程(Thread)是进程的一个实体,是CPU调度和分派的基本单位。线程不可以独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
线程和进程的关系是:线程是属于进程的,线程运行在进程空间内,同一进程所产生的线程共享同一内存空间,当进程退出时该进程所产生的线程都会被强制退出并清除。线程可与属于同一进程的其它线程共享进程所拥有的所有资源,可是其自己基本上不拥有系统资源,只拥有一点在运行中必不可少的信息(如程序计数器、一组寄存器和栈)。
在同一个时间里,同一个计算机系统中若是容许两个或两个以上的进程处于运行状态,这即是多任务。现代的操做系统几乎都是多任务操做系统,可以同时管理多个进程的运行。 多任务带来的好处是明显的,好比你能够边听mp3边上网,与此同时甚至能够将下载的文档打印出来,而这些任务之间丝绝不会相互干扰。那么这里就涉及到并行的问题,俗话说,一心不能二用,这对计算机也同样,原则上一个CPU只能分配给一个进程,以便运行这个进程。咱们一般使用的计算机中只有一个CPU,也就是说只有一颗心,要让它一心多用,同时运行多个进程,就必须使用并发技术。实现并发技术至关复杂,最容易理解的是“时间片轮转进程调度算法”,它的思想简单介绍以下:在操做系统的管理下,全部正在运行的进程轮流使用CPU,每一个进程容许占用CPU的时间很是短(好比10毫秒),这样用户根本感受不出来CPU是在轮流为多个进程服务,就好象全部的进程都在不间断地运行同样。但实际上在任何一个时间内有且仅有一个进程占有CPU。
若是一台计算机有多个CPU,状况就不一样了,若是进程数小于CPU数,则不一样的进程能够分配给不一样的CPU来运行,这样,多个进程就是真正同时运行的,这即是并行。但若是进程数大于CPU数,则仍然须要使用并发技术。
在Linux中,进行CPU分配是以线程为单位的,一个进程可能由多个线程组成,这时状况更加复杂,但简单地说,有以下关系:
总线程数<= CPU数量:并行运行
总线程数> CPU数量:并发运行
并行运行的效率显然高于并发运行,因此在多CPU的计算机中,多任务的效率比较高。可是,若是在多CPU计算机中只运行一个进程(线程),就不能发挥多CPU的优点。
多任务操做系统(如Windows)的基本原理是:操做系统将CPU的时间片分配给多个线程,每一个线程在操做系统指定的时间片内完成(注意,这里的多个线程是分属于不一样进程的).操做系统不断的从一个线程的执行切换到另外一个线程的执行,如此往复,宏观上看来,就好像是多个线程在一块儿执行.因为这多个线程分属于不一样的进程,所以在咱们看来,就好像是多个进程在同时执行,这样就实现了多任务.
分类
根据进程与线程的设置,操做系统大体分为以下类型:
(1) 单进程、单线程,MS-DOS大体是这种操做系统;
(2) 多进程、单线程,多数UNIX(及类UNIX的LINUX)是这种操做系统;
(3) 多进程、多线程,Win32(Windows NT/2000/XP等)、Solaris 2.x和OS/2都是这种操做系统;
(4) 单进程、多线程,VxWorks是这种操做系统。
引入线程带来的主要好处
(1) 在进程内建立、终止线程比建立、终止进程要快;
(2) 同一进程内的线程间切换比进程间的切换要快,尤为是用户级线程间的切换。
===================================================================
用户级线程 (UserLevel Threads — ULT)
内核级线程 (Kernel Supported threads — KST)
对于一切的进程,不管是系统进程仍是用户进程,进程的建立和撤销,以及I/O操做都是利用系统调用进入到内核,由内核处理完成,因此说在KST下, 全部进程都是在操做系统内核的支持下运行的,是与内核紧密相关的。内核空间实现还为每一个内核支持线程设置了一个线程控制快,内核是根据该控制快而感知某个 线程是否存在,并加以控制。
优势:
1. 在多处理器上,内核能够调用同一进程中的多个线程同时工做;
2. 若是一个进程中的一个线程阻塞了,其余线程仍然能够获得运行;
缺点:对于用户线程的切换代价太大,在同一个线程中,从一个线程切换到另外一个线程时,须要从用户态,进入到内核态而且由内核切换。由于线程调度和管理在内核实现。
内核级线程驻留在内核空间,它们是内核对象。有了内核线程,每一个用户线程被映射或绑定到一个内核线程。用户线程在其生命期内都会绑定到该内核线程。一旦用 户线程终止,两个线程都将离开系统。这被称做"一对一"线程映射,如图所示。操做系统调度器管理、调度并分派这些线程。运行时库为每一个用户级 线程请求一个内核级线程。操做系统的内存管理和调度子系统必需要考虑到数量巨大的用户级线程。您必须了解每一个进程容许的线程的最大数目是多少。操做系统为 每一个线程建立上下文。进程的每一个线程在资源可用时均可以被指派处处理器内核。
用户进程ULT仅存在于用户空间中。对于这种线程的建立、撤销、线程之间的同步和通讯等功能,都无需系统调用来实现。对于同一进程的线程之间切换仍然是不须要内核支持的。因此,内核也会是彻底不会知道用户级线程的存在。
可是有一点必须注意:设置了用户级线程的系统,其调度荏苒是以进程为单位进行的哦。
优势:
1. 线程切换不须要转换到内核空间,节省了宝贵的内核空间;
2. 调度算法能够是进程专用,由用户程序进行指定;
3. 用户级线程实现和操做系统无关;
缺点:
1. 系统调用阻塞,同一进程中一个线程阻塞和整个进程都阻塞了。
2. 一个进程只能在一个cpu上得到执行。
用户级线程驻留在用户空间或模式。运行时库管理这些线程,它也位于用户空间。它们对于操做系统是不可见的,所以没法被调度处处理器内核。每一个线程并不具备 自身的线程上下文。所以,就线程的同时执行而言,任意给定时刻每一个进程只可以有一个线程在运行,并且只有一个处理器内核会被分配给该进程。对于一个进程, 可能有成千上万个用户级线程,可是它们对系统资源没有影响。运行时库调度并分派这些线程。如同在图中看到的那样,库调度器从进程的多个线程中 选择一个线程,而后该线程和该进程容许的一个内核线程关联起来。内核线程将被操做系统调度器指派处处理器内核。用户级线程是一种"多对一"的线程映射。
在不少的操做系统中ULT和KLT进行组合,整合了ULT和KLT的优势。
混合线程实现是用户线程和内核线程的交叉,使得库和操做系统均可以管理线程。用户线程由运行时库调度器管理,内核线程由操做系统调度器管理。在这种实现 中,进程有着本身的内核线程池。可运行的用户线程由运行时库分派并标记为准备好执行的可用线程。操做系统选择用户线程并将它映射到线程池中的可用内核线 程。多个用户线程能够分配给相同的内核线程。在图中,进程A在它的线程池中有两个内核线程,而进程B有3个内核线程。进程A的用户线程2和3 被映射到内核线程(2)。进程B有5个线程,用户线程1和2映射到同一个内核线程(3),用户线程4和5映射到内核同一个内核线程(5)。当建立新的用户 线程时,只须要简单地将它映射到线程池中现有的一个内核线程便可。这种实现使用了"多对多"线程映射。该方法中尽可能使用多对一映射。不少用户线程将会映射 到一个内核线程,就像您在前面的示例中所看到的。所以,对内核线程的请求将会少于用户线程的数目。
内核线程池不会被销毁和重建,这些线程老是位于系统中。它们会在必要时分配给不一样的用户级线程,而不是当建立新的用户级线程时就建立一个新的内核线程,而 纯内核级线程被建立时,就会建立一个新的内核线程。只对池中的每一个线程建立上下文。有了内核线程和混合线程,操做系统分配一组处理器内核,进程的线程能够 在这些处理器内核之上运行。线程只能在为它们所属线程指派的处理器内核上运行。
线程上下文
操做系统管理不少进程的执行。有些进程是来自各类程序、系统和应用程序的单独进程,而某些进程来自被分解为不少进程的应用或程序。当一个进程从内核 中移出,另外一个进程成为活动的,这些进程之间便发生了上下文切换。操做系统必须记录重启进程和启动新进程使之活动所须要的全部信息。这些信息被称做上下 文,它描述了进程的现有状态。当进程成为活动的,它能够继续从被抢占的位置开始执行。进程的上下文信息包括:
进程id
指向可执行文件的指针
栈
静态和动态分配的变量的内存
处理器寄存器
进程上下文的多数信息都与地址空间的描述有关。进程的上下文使用不少系统资源,并且会花费一些时间来从一个进程的上下文切换到另外一个进程的上下文。 线程也有上下文。当线程被抢占时,就会发生线程之间的上下文切换。若是线程属于相同的进程,它 们共享相同的地址空间,由于线程包含在它们所属于的进程的地址空间内。这样,进程须要恢复的多数信息对于线程而言是不须要的。尽管进程和它的线程共享了很 多内容,但最为重要的是其地址空间和资源,有些信息对于线程而言是本地且惟一的,而线程的其余方面包含在进程的各个段的内部。
上下文内容 |
进 程 |
线 程 |
指向可执行文件的指针 |
x |
|
栈 |
x |
x |
内存(数据段和堆) |
x |
|
状态 |
x |
x |
优先级 |
x |
x |
程序I/O的状态 |
x |
|
授予权限 |
x |
|
调度信息 |
x |
|
审计信息 |
x |
|
有关资源的信息 ● 文件描述符 ● 读/写指针 |
x |
|
有关事件和信号的信息 |
x |
|
寄存器组 ● 栈指针 ● 指令计数器 ● 诸如此类 |
x |
x |
线程本地(且惟一)的信息包括线程id、处理器寄存器(当线程执行时寄存器的状态,包括程序计数器和栈指针)、线程状态及优先级、线程特定数 据(thread-specific data,TSD)。
线程id是在建立线程时指定的。线程可以访问它所属进程的数据段,所以线程能够读写它所属进程的全局声明数据。进程中一个线程作出的 任何改动均可以被进程中的全部线程以及主线程得到。在多数状况下,这要求某种类型的同步以防止无心的更新。线程的局部声明变量不该当被任何对等线程访问。 它们被放置到线程栈中,并且当线程完成时,它们便会被移走。
© 著做权归做者全部