进程与线程的优缺点

时间:2023-01-03 16:43:13
凡用兵之法,驰车千驷,革车千乘,带甲十万,千里馈粮,则内外之费,宾客之用,胶漆之材,车甲之奉,日费千金,然后十万之师举矣。

这是《孙子兵法》“第二篇•作战篇”中的一句话,每当提起进程或线程的概念都使我想起战法和谋略。进程之于操作系统来说乃将,线程之于操作系统来说乃兵,正所谓将兵之道,国之大事,死生之地,不可不察也。

操作系统管理和控制着计算机系统中的硬件和软件资源、组织计算机工作流程以及用户交互,它就好比电脑王国中的国王。

专业定义

进程(Process)是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位.
线程(Thread)是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源.
一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行.

进程与线程的概念

我们首先来介绍进程,进程是什么呢?直观的讲,进程就是正在执行的程序,一个进程通常就是一个正在执行的应用程序。从Windows角度讲,进程是含有内存和资源并安置线程的地方。进程中的资源可以包括文件句柄、线程、用户资源(对话框或字符串)、GDI资源(设备环境DC和画笔等)等。进程往往与一个任务挂钩,就像上面我们提到的“将”,操作系统负责分配资源让进程率领众线程完成某种任务。也是因此,Windows提供一个叫做“任务管理器”的工具可以让我们查看和管理进程,如下图-1所示:

进程与线程的优缺点 图-1  任务管理器

我们不妨简单介绍几个当前运行进程的含义。比如上面的avgas.exe是我本机杀毒软件卡巴斯基的进程;notepad.exe是我当前打开的记事本程序的进程;alg.exe是一个系统进程,用于进行网络共享相关的网关服务。这些启动的进程跟本机环境有关,当我们启动一个应用程序(或说一个任务)时通常也就启动了一个进程。从上图可以看出每一个进程占有一定的内存空间和CPU,当然进程还会有其他系统资源,内存和CPU只是操作系统便于我们了解进程的运行情况向我们公布的进程的重要信息。

所以准确的讲,进程就是一个可执行的程序一次运行的过程,它是系统进行资源分配和调度的一个独立单位。明白进程是系统进行资源分配和调度的单位非常重要,内存和CPU都是系统资源,当一个程序被调入内存开始执行时就变成了进程,此时操作系统便为其分配了这些相关的资源并且负责进行调度。进程是将,这个将直接对操作系统这个国王负责,国王可以分配给他一定的土地和俸禄(对应系统资源)并指派他去完成特定的任务。一个国家日理万机的大将可以有很多,这也就是操作系统多进程的概念,操作系统这个国王负责调兵遣将。

按照定义,线程是操作系统分配处理器(CPU)时间的基本单元,是系统中最小的执行单元。如前所述,进程如将,线程如兵,操作系统创建并控制进程,进程包含和控制线程。我们知道国王和将帅自己并不去攻城掠地,他们只是坐阵指挥。那么实际上真正进行攻城掠地的是兵(线程)。兵也有自己的资源(系统会为线程初始化一个线程内核对象,还有一块1M左右的内存堆栈)。作为将要善于谋略,善于部署,善于将兵,拥兵十万不如精甲十千。作为兵要众志成城、竭尽全力去完成自己的任务。所以线程不可滥用,进程应当精简(一个进程只需做一个任务就够了)。

多进程决定了操作系统的多任务。但是我们知道我们往往只有一个CPU,一个CPU在同一时间只能做一件事情,多任务又是怎么实现的呢?我们知道要真正完成某个任务的是线程,对于进程来讲至少会带有一个默认的线程,我们称之为主线程。我们先假设进程都带有一个线程。线程要执行就需要CPU,我们知道现今CPU因为执行速度非常快,它没有必要单独为一个线程服务,因此它将自己一秒的时间进行切片,每片有1毫秒左右(这个微软没有具体说明,是由操作系统内部参数来控制这个时间值,具体来说跟CPU速度有关,速度越快时间片切的越小),然后它就以时间片为单位向外提供服务。比如在一秒钟内A线程占有10个时间片,B线程占有30个时间片……每一秒都这样分配了以后,操作系统负责CPU的切换,于是一秒钟过后所有线程都执行了,整体看上去好像所有的进程是在同时运行,这就是操作系统多任务的实现方式,是通过不断切换线程执行实现的。

下面是一个CPU利用图(图-2),操作系统负责进行线程之间的切换:

进程与线程的优缺点 图-2  线程原理图

从上图首先可以看出,对于单个线程来讲抢占的CPU时间越多它完成的事情就越多,也可以说是执行就越快。要让某个线程抢占CPU的能力增加,你可以提高该线程的优先级,通常来说优先级越高的线程抢占CUP能力越强,当然,大部分情况下不需要这么做。因为线程是抢占CPU的主力军,所以我们可以用增加线程数目的方式提高进程的执行速度。从一般意义上讲,进程在完成任务时用的线程越多任务就完成的越快,正所谓三军之众,可使必受敌而无败。我们从CPU时间片的角度举一个通俗的例子,假如给你一星期时间,你将它切片,每天为一片。假如你有三个女朋友,你和这三个女友的感情进展就可以看作是三条线程,那么如果她们其中一个获得4个时间片去发展感情,另外两个都是1个时间片,如此常此以往,很显然与拥有四个时间片的女友感情进展最快。

进程和线程的区别

进程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。如果有兴趣深入的话,建议看看《现代操作系统》或者《操作系统的设计与实现》。对就个问题说得比较清楚。

一个程序至少有一个进程,一个进程至少有一个线程. 线程的划分尺度小于进程,使得多线程程序的并发性高。
另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。
线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。

进程与线程的优缺点

进程的优点:

1)、顺序程序的特点:具有封闭性和可再现性;

2)、程序的并发执行和资源共享。多道程序设计出现后,实现了程序的并发执行和资源共享,提高了系统的效率和系统的资源利用率。

进程的缺点:

操作系统调度切换多个线程要比切换调度进程在速度上快的多。而且进程间内存无法共享,通讯也比较麻烦。线程之间由于共享进程内存空间,所以交换数据非常方便;在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销。

线程的优点:

1)、它是一种非常"节俭"的多任务操作方式。在Linux系统下,启动一个新的进程必须分配给它独立的地址空间,建立众多的数据表来维护它的代码段、堆栈段和数据段,这是一种"昂贵"的多任务工作方式。而运行于一个进程中的多个线程,它们彼此之间使用相同的地址空间,共享大部分数据,启动一个线程所花费的空间远远小于启动一个进程所花费的空间,而且,线程间彼此切换所需的时间也远远小于进程间切换所需要的时间。当然,在具体的系统上,这个数据可能会有较大的区别;

2)、线程间方便的通信机制,由于同一进程下的线程之间共享数据空间,所以一个线程的数据可以直接为其它线程所用,这不仅快捷,而且方便;

3)、使多CPU系统更加有效。操作系统会保证当线程数不大于CPU数目时,不同的线程运行于不同的CPU上;

4)、改善程序结构。一个既长又复杂的进程可以考虑分为多个线程,成为几个独立或半独立的运行部分,这样的程序会利于理解和修改。

线程的缺点:
1)、调度时, 要保存线程状态,频繁调度, 需要占用大量的机时;
2)、程序设计上容易出错(线程同步问题)。

进程与线程的管理

为了对系统中的进程和线程进行管理,不但要有进程控制块PCB,而且要为每个线程均设置一个线程控制块TCB。这些PCB和TCB不但描述和记录了每个进程和线程属性和调度所需的数据,而且是说明这些进程和线程存在的标志。

进程控制块:PCB是操作系统中最重要的数据结构。PCB的作用不但是记录进程的属性信息,以便操作系统对进程进行控制和管理,而且PCB标志着进程的存在,操作系统根据系统中是否有该进程的进程控制块PCB而知道该进程存在与否。系统建立进程的同时就建立该进程的PCB,在撤销一个进程时,也就撤销其PCB,故进程的PCB对进程来说是它存在的具体的物理标志和体现。一般PCB包括以下三类信息:进程标识信息;处理器状态信息;进程控制信息。

在基于多线程基础上的系统中进程控制块和线程控制块都是采用面向对象技术来开发的,把进程和线程均视作是对象。因而PCB和TCB均用进程对象和线程对象来描述。在进程管理和线程管理中,往往都用链指针将线程控制块或线程对象【进程控制块或进程对象】,按他们的所处状态链结成相应的线程队列【进程队列】来加以管理。如就绪队列,阻塞队列,运行队列等

进程与程序的关系

进程和程序之间的区别是很微妙的,但却非常重要。一个类比可以使我们更容易理解这一点。想象一位有一手好厨艺的计算机科学家正在为他的女儿烘制生日蛋糕。他有做生日蛋糕的食谱,厨房里有所需的原料:面粉、鸡蛋、糖、香草汁等等。在这个比喻中,做蛋糕的食谱就是程序(即用适当形式描述的算法),计算机科学家就是处理机(CPU),而做蛋糕的各种原料就是输入数据。进程就是厨师阅读食谱、取来各种原料、以及烘制蛋糕的一系列动作的总和。
现在假设计算机科学家的儿子哭着跑了进来,说他被一只蜜蜂螫了。计算机科学家就记录下他照着食谱做到哪儿了(保存进程的当前状态),然后拿出一本急救手册,按照其中的指示处理螫伤。这里,我们看到处理机从一个进程(做蛋糕)切换到另一个高优先级的进程(实施医疗救治),每个(进程)拥有各自的程序(食谱和急救书)。当蜜蜂螫伤处理完之后,计算机科学家又回来做蛋糕,从他离开时的那一步继续做下去。
这里的关键思想是:一个进程是某种类型的一个活动,它有程序、输入、输出、及状态。单个处理机被若干进程共享,它使用某种调度算法决定何时停止一个进程的工作,并转而为另一个进程提供服务。