.NET面试题系列[16] - 多线程概念(1)

.NET面试题系列目录

这篇文章主要是各个百科中的一些摘抄,简述了进程和线程的来源,为何出现了进程和线程。html

操做系统层面中进程和线程的实现

操做系统发展史

直到20世纪50年代中期,还没出现操做系统,计算机工做采用手工操做方式。程序员将对应于程序和数据的已穿孔未的纸带(或卡片)装入输入机,而后启动输入机把程序和数据输入计算机内存,接着经过控制台开关启动程序针对数据运行;计算完毕,打印机输出计算结果;用户取走结果并卸下纸带(或卡片)后,才让下一个用户上机。linux

手工操做方式的两个特色:程序员

(1)用户独占全机。不会出现因资源已被其余用户占用而等待的现象,但资源的利用率低。面试

(2)CPU等待手工操做。CPU的利用不充分。算法

20世纪50年代后期,出现人机矛盾:手工操做的慢速度和计算机的高速度之间造成了尖锐矛盾,手工操做方式已严重损害了系统资源的利用率(使资源利用率降为百分之几,甚至更低),不能容忍。惟一的解决办法:只有摆脱人的手工操做,实现做业的自动过渡。这样就出现了成批处理。编程

批处理系统(50年代后期)

批处理系统的追求目标是提升系统资源利用率和系统吞吐量,以及做业流程的自动化。批处理系统的一个重要缺点是不提供人机交互能力,给用户使用计算机带来不便。安全

批处理是指用户将一批做业提交给操做系统后就再也不干预,由操做系统控制它们自动运行。这种采用批量处理做业技术的操做系统称为批处理操做系统。批处理操做系统分为单道批处理系统和多道批处理系统。批处理操做系统不具备交互性,它是为了提升CPU的利用率而提出的一种操做系统。服务器

早期的批处理系统属于单道批处理系统,其目的是减小做业间转换时的人工操做,从而减小CPU的等待时间。它的特征是内存中只容许存放一个做业,即当前正在运行的做业才能驻留内存,做业的执行顺序是先进先出,即按顺序执行。网络

因为在单道批处理系统中,一个做业单独进入内存并独占系统资源,直到运行结束后下一个做业才能进入内存,看成业进行I/O操做时,CPU只能处于等待状态,所以,CPU利用率较低,尤为是对于I/O操做时间较长的做业。为了提升CPU的利用率,在单道批处理系统的基础上引入了多道程序设计技术,这就造成了多道批处理系统,即在内存中可同时存在若干道做业,做业执行的次序与进入内存的次序无严格的对应关系,由于这些做业是经过必定的做业调度算法来使用CPU的,一个做业在等待I/O处理时,CPU调度另一个做业运行,所以CPU的利用率显著地提升了。数据结构

批处理系统中,一个做业能够长时间地占用CPU。而分时系统中,一个做业只能在一个时间片的时间内使用CPU。批处理系统不是严格意义上的操做系统。

多道程序设计与多道批处理系统(60年代中期)

多道程序技术(Multiprogramming)运行的特征:多道、宏观上并行、微观上串行。多道程序技术的提出是为了改善CPU的利用率。它须要硬件支持,并令CPU调度其余硬件工做。

  (1)多道:计算机内存中同时存放几道相互独立的程序(一开始称为做业,后来演化为进程);

  (2)宏观上并行:同时进入系统的几道程序都处于运行过程当中,即它们前后开始了各自的运行,但都未运行完毕;

  (3)微观上串行:实际上,各道程序轮流地用CPU,并交替运行。

所谓多道程序设计指的是容许多个程序同时进入一个计算机系统的主存储器并启动进行计算的方法。也就是说,计算机内存中能够同时存放多道(两个以上相互独立的)程序,它们都处于开始和结束之间。从宏观上看是并行的,多道程序都处于运行中,而且都没有运行结束;从微观上看是串行的,各道程序轮流使用CPU,交替执行。引入多道程序设计技术的根本目的是为了提升CPU的利用率,充分发挥计算机系统部件的并行性。现代计算机系统都采用了多道程序设计技术。

例如,若是一个进程有20%的时间使用CPU进行计算,另外80%的时间用来进行I/O,则在单道编程下CPU的利用率只有20%,由于在I/O时间,CPU没有事情作(只有一个进程)。

若是是支持两个进程的操做系统,即便用2道编程,则CPU只在两个进程同时进行I/O时才会处于闲置状态,所以CPU利用率将会提升到:1-0.8*0.8=0.36=>36%。同理,若是同时运行更多的进程,CPU利用率会逐步提升,直到某个临界点为止。(PS:这里的例子忽略了进程切换所须要的系统消耗)

虽然用户独占全机资源,而且直接控制程序的运行,能够随时了解程序运行状况,但这种工做方式因独占全机形成资源效率极低。因而一种新的追求目标出现了:既能保证计算机效率,又能方便用户使用计算机。20世纪60年代中期,计算机技术和软件技术的发展使这种追求成为可能。

分时操做系统

分时操做系统是使一台计算机采用时间片轮转的方式同时为几个、几十个甚至几百个用户服务的一种操做系统。

把计算机与许多终端用户链接起来,分时操做系统将系统处理机时间与内存空间按必定的时间间隔,轮流地切换给各终端用户的程序使用。因为时间间隔很短,每一个用户的感受就像他独占计算机同样。分时操做系统的特色是可有效增长资源的使用率。

分时系统是当今计算机操做系统中最广泛使用的一类操做系统。实现多任务处理的方式有抢占式(Preemption)与协做式。协做式环境下,下一个进程被调度的前提是当前进程主动放弃时间片;抢占式环境下,操做系统彻底决定进程调度方案,操做系统能够剥夺耗时长的进程的时间片,提供给其它进程。

进程(Process)

每一个程序最终都会加载到内存中运行。多道程序设计的出现提供了进程的雏形 – 系统内部能够存放多于一个做业。分时操做系统中,系统内部也能够同时存在超过一个程序,这些同时存在于计算机内存中的程序就被称为进程。但当咱们在一个现代系统上运行一个程序时,会获得一个假象,就好像咱们的程序是系统中当前运行着的惟一的程序

进程的实现:经过操做系统的内存分配和调度。OS经过进程控制块管理进程。经过虚拟内存实现进程隔离,一个进程没法访问其余进程正在占有的资源。但不安全的操做系统例如DOS,任何进程均可以访问其余进程的资源。

进程让每一个用户感受本身在独占CPU 

进程是多道编程天然而然的产物,而多道编程的目的则是为了提升计算机CPU的利用率(或者说系统的吞吐量)。

三个视角看进程模型

(1)物理视角:从物理内存的分配来看,每一个进程占用一片内存空间,从这点上看,进程其实就是内存的某片空间。因为在任意时刻,一个CPU只能执行一条指令,所以任意时刻在CPU上执行的进程只有一个,而到底执行哪条指令是由物理程序计数器指定。所以,在物理层面,全部进程共用一个程序计数器,只是CPU在不停地作进程切换。

(2)逻辑视角:从逻辑层面来看,每一个进程均可以执行,也能够暂时挂起让别的进程执行,以后又能够接着执行。因此,进程须要想办法保持状态才能在下次接着执行时从正确的地点(即上下文)开始。所以,每一个进程都有本身的计数器,记录其下一条指令所在的位置。(从逻辑上来讲,程序计数器能够有多个)

(3)时序视角:从时间来看,每一个进程都必须往前推动。在运行必定时间后,进程都应该完成了必定的工做量。换句话说,每次进程返回,它都处在上次返回点以后。

在现代操做系统中,进程管理和调度是操做系统的功能之一,特别是多任务处理的情况下,这是必要的功能。操做系统将资源分配给各个进程,让进程间能够分享与交换信息,保护每一个进程拥有的资源,不会被其余进程抢走,以及使进程间可以同步(必要的话)。为了达到这些要求,操做系统为每一个进程分配了一个数据结构,用来描述进程的状态,以及进程拥有的资源。操做系统能够经过这个数据结构,来控制每一个进程的运做。

如何实现进程

(1)物理基础:进程的物理基础是程序,程序又运行在计算机上,所以计算机上要运行程序首先要解决进程的存储:给进程分配内存,使其安身立命。因为多个进程可能同时并存,所以须要考虑如何让多个进程共享同一个物理内存而不发生冲突。OS经过内存管理(虚拟内存和进程隔离)来解决这个问题。

(2)进程切换:进程运行其实是指进程在CPU上执行,那么如何将CPU在多个进程之间进行切换也是一个问题。OS经过进程调度来解决这个问题。所谓进程调度,就是决定在何时让什么进程来使用CPU,并在调度切换进程时,不会损失以前工做的数据。

虚拟内存和进程隔离

虚拟内存是计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续的可用的内存(一个连续完整的地址空间),而实际上,它一般是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在须要时进行数据交换。目前,大多数操做系统都使用了虚拟内存,如Windows家族的“虚拟内存”;Linux的“交换空间”等。

电脑中所运行的程序均需经由内存执行,若执行的程序占用内存很大或不少,则会致使内存消耗殆尽。当内存耗尽时,Windows会用虚拟存储器进行补偿,它将计算机的RAM和硬盘上的临时空间组合。当RAM运行速率缓慢时,它便将数据从RAM移动到称为“分页文件”的空间中。将数据移入分页文件可释放RAM,以便完成工做。通常而言,计算机的RAM容量越大,程序运行得越快。若计算机的速率因为RAM可用空间匮乏而减缓,则可尝试经过增长虚拟内存来进行补偿。可是,计算机从RAM读取数据的速率要比从硬盘读取数据的速率快,于是扩增RAM容量(可加内存条)是最佳选择。

虚拟内存是Windows做为内存使用的一部分硬盘空间,在硬盘上其实就是一个硕大无比的文件,文件名是PageFile.sys,一般状态下是看不到的。必须关闭资源管理器对系统文件的保护功能才能看到这个文件。虚拟内存有时候也被称为是“页面文件”就是从这个文件的文件名中来的。

进程隔离是为保护操做系统中进程互不干扰而设计的一组不一样硬件和软件的技术。这个技术是为了不进程A写入进程B的状况发生。进程的隔离实现使用了虚拟内存。进程A的虚拟地址和进程B的虚拟地址不一样,这样就防止进程A将数据信息写入进程B。

进程隔离的安全性经过禁止进程间内存的访问能够方便实现。相比之下,一些不安全的操做系统(例如DOS)可以容许任何进程对其余进程的内存进行写操做。

进程调度(Process Scheduling)

在多进程的环境里,虽然从概念上看,有多个进程在同时执行,但在单个CPU下,在任什么时候刻只能有一个进程处于执行状态,而其余进程则处于非执行状态。那么问题来了,咱们是如何肯定在任意时刻到底由哪一个进程执行,哪些不执行呢?这就涉及到进程管理的一个重要组成部分:进程调度。

进程调度是操做系统进程管理的一个重要组成部分,其任务是选择下一个要运行的进程。发生时钟中断是激发调度的其中一个可能。当调度结束,选择下一个要运行的进程以后,若是选择的进程不是如今正在运行的进程,CPU要进行上下文交换(Context Switching)。

咱们必须解决以下问题:

  1. 使用某种调度算法安排多个进程顺序执行
  2. 对于目前正在休息的进程,须要让它在从新运行时,知道本身挂起以前的状态。因而做为进程自己,它是没有感受本身被中断过的,即上下文交换

基本调度算法

通常的程序任务分为三种:CPU计算密集型、IO密集型与平衡(计算与IO各半)型,对于不一样类型的程序,调度须要达到的目的也有所不一样。对于IO密集型,响应时间最重要;对于CPU密集型,则周转时间最重要;而对于平衡型,进行某种响应和周转之间的平衡就显得比较重要。所以,进程调度的目标就是要达到极小化平均响应时间、极大化系统吞吐率、保持系统各个功能部件均处于繁忙状态和提供某种貌似公平的机制。

先来先服务(FCFS)算法

先来先服务(FCFS)算法是一种最多见的算法,它是人的本性中的一种公平观念。其优势就是简单且实现容易,缺点则是短的工做有可能变得很慢,由于其前面有很长的工做在执行,这样就会形成用户的交互式体验也比较差。例如排队办理业务时,你要办理的业务只须要几分钟就能够办好,可是你前面的一我的办理的事情很复杂须要1个小时,这时你须要在他后面等好久,因而你就想到:要是每一个人轮流办理10分钟事务的话,那该多好!因而就出现了时间片轮转算法。

时间片轮转算法

时间片轮转是对FCFS算法的一种改进,其主要目的是改善短程序的响应时间,实现方式就是周期性地进行进程切换。时间片轮转的重点在于时间片的选择,须要考虑多方因素:若是运行的进程多时,时间片就须要短一些;进程数量少时,时间片就能够适当长一些。所以,时间片的选择是一个综合的考虑,权衡各方利益,进行适当折中。

可是,时间片轮转的系统响应时间也不必定老是比FCFS的响应时间短。时间片轮转是一种大锅饭的作法,可是现实生活中倒是走的“一部分人先富,先富带动后富”的路线。例如,若是有30个任务,其中一个任务只须要1秒时间执行,而其余29个任务须要30秒钟执行,若是由于某种缘由,这个只要1秒钟的任务排在另外29个任务的后面轮转,则它须要等待29秒钟才能执行(假定时间片为1秒)。因而,这个任务的响应时间和交互体验就变得很是差。所以,短任务优先算法被提出。

短任务优先算法

短任务优先算法的核心是全部的任务并不都同样,而是有优先级的区分。具体来讲,就是短任务的优先级比长任务的高,而咱们老是安排优先级高的任务先运行(这可能会致使饥饿)。

短任务优先算法又分为两种类型:一种是非抢占式,一种是抢占式。非抢占式当已经在CPU上运行的任务结束或阻塞时,从候选任务中选择执行时间最短的进程来执行。而抢占式则是每增长一个新的进程就须要对全部进程(包括正在CPU上运行的进程)进行检查,谁的时间短就运行谁。

因为短任务优先老是运行须要执行时间最短的程序,所以其系统平均响应时间在以上几种算法中是最优的,这也是短任务优先算法的优势。但短任务优先算法也有缺点:一是可能形成长任务永远没法获得CPU时间从而致使“饥饿”。二是如何知道每一个进程还须要运转多久?因而为了解决第一个缺点,优先级调度算法被提出。而第二个缺点则能够采起一些启发式的方法来进行估算,目前不少的人工智能算法均可以作这个事。

优先级调度算法

优先级调度算法给每一个进程赋予一个优先级,每次须要进程切换时,找一个优先级最高的进程进行调度。这样若是赋予长进程一个高优先级,则该进程就不会再“饥饿”。事实上,短任务优先算法自己就是一种优先级调度,只不过它给予短进程更高的优先级而已。

该算法的优势在于能够赋予重要的进程以高优先级以确保重要任务可以获得CPU时间,其缺点则有二:一是低优先级的进程可能会“饥饿”,二是响应时间没法保证。第一个缺点能够经过动态地调节任务的优先级解决,例如一个进程若是等待时间过长,其优先级将持续提高,超越其余进程的优先级,从而获得CPU时间。第二个缺点能够经过将一个进程优先级设置为最高来解决,但即便将优先级设置为最高,但若是每一个人都将本身的进程优先级设置为最高,其响应时间仍是没法保证。

混合调度算法

以前的算法都存在必定缺点,那么能否有一个算法混合他们的优势,摒弃它们的缺点,这就是所谓的混合调度算法。混合调度算法将全部进程分为不一样的大类,每一个大类为一个优先级。若是两个进程处于不一样的大类,则处于高优先级大类的进程优先执行;若是处于同一个大类,采用时间片轮转算法来执行。

进程状态保存

当发生上下文切换时,进程和CPU互动的资料(存储在CPU的寄存器中)须要保存。由于这些资料很快就会被另外一个进程覆盖(经过和CPU的互动)。这些资料通常以名为进程控制块(Process Control Block,PCB)的数据结构储存起来。通常来讲,这些资料应该包含:寄存器、程序计数器、状态字、栈指针、优先级、进程ID、建立时间、所耗CPU时间、当前持有的各类句柄等等。

进程本身的资料是不须要保存的,由于它储存在内存中一块固定的空间,并且进程隔离已经保证了这些资料是安全的。当进程恢复运行时,它只须要再次回到属于它的空间就能够找到上次全部的资料。

上下文切换(Context Switching)

   简单的说,上下文切换就是当进程调度致使要切换进程时,当前运行的进程将资料储存进进程控制块,而后经过调度算法选择下一个进程,被选中的(当前在睡眠)的进程从进程控制块中得到本身以前工做的信息,而后从新开始工做的过程。

   在三种状况下可能会发生上下文切换:中断处理,多任务处理,用户态切换。在中断处理中,其余程序的行为打断了当前正在运行的程序。当CPU接收到中断请求时,会在正在运行的程序和发起中断请求的程序之间进行一次上下文切换。在多任务处理中,CPU会在不一样程序之间来回切换,每一个程序都有相应的处理时间片,CPU在两个时间片的间隔中进行上下文切换。用户态切换则是用户本身的行为,例如从游戏中切出来,看一会网站的行为。

   上下文切换一般是计算密集型的。也就是说,它须要至关可观的处理器时间,会对性能形成负面影响。类似的,线程也存在上下文切换。

进程间通讯(Inter-Process Communication)

进程间通讯(IPC,Inter-Process Communication),指至少两个进程或线程间传送数据或信号的一些技术或方法。每一个进程都有本身的一部分独立的系统资源,彼此是隔离的。为了能使不一样的进程互相访问资源并进行协调工做,才有了进程间通讯。举一个典型的例子,使用进程间通讯的两个应用能够被分类为客户端和服务器,客户端进程请求数据,服务端回复客户端的数据请求。有一些应用自己既是服务器又是客户端,这在分布式计算中,时常能够见到。这些进程能够运行在同一计算机上或网络链接的不一样计算机上。

管道(Pipeline)

在类Unix操做系统(以及一些扩展例如Windows)中,管道(Pipeline)是原始的软件管道:便是一个由标准输入输出连接起来的进程集合,因此每个进程的输出(stdout)被直接做为下一个进程的输入(stdin)。管道所占的空间既能够是内存也能够是磁盘。

要建立一个管道,一个进程只须要调用管道建立的系统调用(系统API)便可,该系统调用所作的事情就是在某种存储介质上划出一片空间,赋给其中一个进程写的权利,另外一个进程读的权利。

C#中相似的通讯机制能够参考此文:http://www.cnblogs.com/yukaizhao/archive/2011/08/04/system-io-pipes.html

套接字(Socket)

套接字(Socket)的功能很是强大,能够支持不一样层面、不一样应用、跨网络的通讯。使用套接字进行通讯须要双方均建立一个套接字,其中一方做为服务器方,另一方做为客户方。服务器方必须首先建立一个服务区套接字,而后在该套接字上进行监听,等待远方的链接请求。客户方也要建立一个套接字,而后向服务器方发送链接请求。服务器套接字在受到链接请求以后,将在服务器方机器上新建一个客户套接字,与远方的客户方套接字造成点到点的通讯通道。以后,客户方和服务器方即可以直接经过相似于send和recv的命令在这个建立的套接字管道上进行交流了。

信号与信号量

信号相似于咱们生活中的电报,若是你想给某人发一封电报,就拟好电文,而后将电文和收报人的信息都交给电报公司。电报公司则将电报发送到收报人所在地的邮局,并通知收报人来取电报。其中,发报文时无需收报人事先知道,也无需进行任何协调。若是对方选择不对信号作出响应,则将被OS终止运行。

在计算机中,信号就是一个内核对象或者是一个内核数据结构。发送方将该数据结构的内容填好,并指明该信号的目标进程后,发出特定的软件中断(这就是一个发电报的操做)。OS接收到特定的中断请求后,知道是有进程要发送信号,因而到特定的内核数据结构里查找信号接收方,并进行通知。接到通知的进程则对信号进行相应处理。

信号量来源于铁路的运行:在一条单轨铁路上,任什么时候候只容许有一列火车行驶在该铁路上,而管理这条铁路的系统就是信号量。任何一列火车必须等到代表该铁路能够行驶的信号后才能进入轨道。当列车进入后,须要将信号改成禁止状态进入来防止别的列车同时进入。而当列车驶出单轨后,则须要将信号变回容许进入状态,这很像之前的旗语。固然,经过联想到咱们实际开发中常常用的锁,这就更容易理解了。

在计算机中,信号量实际上就是一个简单整数。一个进程在信号变为0或1的状况下推动,并将信号变为1或0来防止别的进程同时推动。当该进程完成任务后,则将信号再改成0或1,从而容许其余进程执行。从而咱们也能够看出,信号量已经不仅是一种通讯机制,更是一种同步机制。

在系统中,给予每个进程一个信号量,表明每一个进程目前的状态,未获得控制权的进程会在特定地方被强迫停下来,等待能够继续进行的信号到来。若是信号量是一个任意的整数,一般被称为计数信号量(Counting semaphore),或通常信号量(general semaphore);若是信号量只有二进制的0或1,称为二进制信号量(binary semaphore)。在linux系中,二进制信号量(binary semaphore)又称Mutex。

计数信号量具有两种操做动做,以前称为V(又称signal())与P(wait())。V操做会增长信号量S的数值,P操做会减小它。

运做方式:

  1. 初始化,给它一个非负数的整数值。
  2. 运行 P(wait()),信号量S的值将被减小。企图进入临界区块的进程,须要先运行 P(wait())。当信号量S减为负值时,进程会被挡住,不能继续;当信号量S不为负值时,进程能够获准进入临界区块。(信号量经过这个机制,控制进入临界区块的进程的数量)
  3. 运行 V(又称signal()),信号量S的值会被增长。结束离开临界区块的进程,将会运行 V(又称signal())。当信号量S不为负值时,先前被挡住的其余进程,将可获准进入临界区块。

C#对信号量的实现是Mutex和Semaphore。

共享内存

两个进程共同拥有同一片内存。对于这片内存中的任何内容,两者都可以访问。要使用共享内存进行通讯,进程A首先须要建立一片内存空间做为通讯用,而其余进程B则将这片内存映射到本身的(虚拟)地址空间。这样,进程A读写本身地址空间中对应共享内存的区域时,就是在和进程B进行通讯。

消息队列

消息队列是一列具备头和尾的消息排列,新来的消息放在队列尾部,而读取消息则从队列头部开始。

这样看来,它和管道十分相似,一头读,一头写?的确,看起来很像管道,但又不是管道:

(1)消息队列无固定的读写进程,任何进程均可以读写;而管道须要指定谁读和谁写;

(2)消息队列能够同时支持多个进程,多个进程能够读写消息队列;即所谓的多对多,而管道是点对点;

(3)消息队列只在内存中实现,而管道还能够在磁盘上实现;

线程

线程是CPU的一个虚拟。

微软决定在一个进程中运行应用程序的每一个实例。进程是应用程序要使用的资源的一个集合。当程序在进程中开始运行时,它就如同被关进了一个密闭的空间,里面有全部它须要的东西。不一样的密闭空间不会发生关系,任何一个进程死掉不会致使整个系统崩溃。进程有本身的虚拟地址空间,确保这个进程使用的代码不会被其余进程访问。而且当进程失去响应时,系统仍然能够工做,还能够用其余进程杀死失去响应的进程。

听起来彷佛没问题?但虽然应用程序与操做系统之间已经透过进程来达到隔离和保护的效果,但是它们仍然有共享的资源:CPU若是机器只有一个CPU,那么当某个应用程序进入无穷循环,那个惟一的CPU就会忙着跑无穷循环而无暇照顾其余应用程序,形同锁住。因而,用户会发现每一个应用程序都没法响应了,不管鼠标点在哪里都不起做用。为了解决这个CPU没法分身的问题,线程(thread)便应运而生。

Windows经过线程来虚拟化CPU。线程使得每一个进程(至少拥有一个线程)拥有CPU的一个“分身”(称为逻辑CPU,真正的CPU称为物理CPU)。当一个线程进入无限循环时,其余线程仍然能够继续运行。

线程的好处以下:

1. 在不少现代的大型程序(例如Word)中,一个程序同时在作不少事情。当咱们使用Microsoft Word时,其实是打开了多个线程。这些线程一个负责显示,一个负责接收输入,一个定时进行存盘。这些线程一块儿运转,让咱们感受到输入和显示同时发生,而不用键入一些字符等待一下子才显示到屏幕上。在不经意间,Word还能按期自动保存。这须要多个线程互相同步或互斥的并行完成工做,而将这些工做分解到不一样的线程中去无疑简化了编程模型。

2. 由于线程相比进程来讲更加轻量,因此线程的建立和销毁的代价更小。

3. 线程提升了性能,虽然线程宏观上是并行的,但微观上倒是串行(经过时间片)。从CPU角度线程没法提高性能,但若是某些线程涉及到等待资源(好比IO,等待输入)时,多线程容许进程中的其它线程继续执行而不是整个进程被阻塞,所以提升了CPU的利用率,从这个角度会提高性能(和多道程序设计相同)。

4. 在多CPU或多核的状况下,使用线程不只仅在宏观上并行,在微观上也是并行的。

在线程模式下,一个进程至少有一个线程,也能够有多个线程。线程和进程既有类似又有不一样之处。 

类似:

  1. 线程能够当作是轻量级的进程。因此使用了进程以后,再引入线程并不能提升性能。
  2. 不一样的线程和不一样的进程均可以通讯。
  3. 线程和进程都有优先级,都须要系统进行调度。
  4. 线程和进程都有状态。 

不一样之处:

  1. 线程的任务是虚拟化CPU,令CPU再也不是全部进程共享的一个互斥元件,进程的任务则是提升CPU的使用效率。
  2. 线程做为调度和分派的基本单位,而进程做为资源拥有的基本单位。同一进程中,线程的切换不会引发进程的切换,但从一个进程中的线程切换到另一个进程中的线程时,将会引发进程切换。
  3. 一个进程能够包括多个线程,并且至少要有一个前台线程。
  4. 进程之间经过虚拟内存隔离,但一个进程中的线程共享全部进程的资源。

同进程同样,线程也须要调度,通讯和同步。

 

参考资料

http://www.cnblogs.com/edisonchou/p/5022508.html

https://zh.wikipedia.org/wiki/%E8%A1%8C%E7%A8%8B%E9%96%93%E9%80%9A%E8%A8%8A

http://www.cnblogs.com/edisonchou/p/5037403.html

http://www.cnblogs.com/CareySon/archive/2012/05/04/ProcessAndThread.html

百度百科

相关文章
相关标签/搜索