进程与线程的总结和区别

来源:互联网 发布:centos 创建文件夹 编辑:程序博客网 时间:2024/05/29 09:13



对于进程和线程的区别,很多面试或者笔试都有涉及到。我想很多朋友跟我一样,对他们都仅限于一些很粗很广的定义和区分,对于很多细节一下子回答出来还是有一定难度的。下面我将对进程和线程做一个系统的总结,供大家参考。如文中有不妥的地方,欢迎大家指正。

 一、概念上区分

程序:程序本身只是指令、数据及其组织形式的描述,是一个静态的概念。

进程:进程是操作系统的基础,也是程序的基本执行实体,是一个动态的概念。若干进程有可能与同一个程序相关系,且每个进程皆可以同步(循序)或异步(平行)的方式独立运行。在面向进程设计的系统中,如早期的UNIXLinux2.4及更早的版本)中,进程是程序的基本执行实体也是系统分配和调度资源的基本单元;在面向线程设计的系统中,(如当代多数操作系统、Linux 2.6及更新的版本)中,进程本身不是基本运行单位,而是线程的容器,在资源调度和分配上与面向进程设计的系统唯一区别是:进程是分配和调度除CPU以外的资源的基本单元,而线程才是分配和调度CPU的基本单元

线程:是操作系统进行CPU调度的最小单元。寄生于进程中,是进程的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。在UNIXSUN系统中被称为轻量级线程,但轻量级线程更多的是指内核线程,而把用户线程称为线程。每个进程至少有一个线程,如果程序只有一个线程,那就是进程本身。

 

二、基本状态以及状态转换

1、进程

进程的基本状态:就绪、执行、阻塞

         就绪状态:指进程获得了除CPU以外的所有必要资源,只要获得CPU资源便可执行。

         执行状态:此时,进程正在执行计算任务,处理指定的操作。

         阻塞状态:正在执行的进程,由于等待某个事件发生而无法执行时,便放弃处理机而处于阻塞状态。引起进程阻塞的事件可有多种,例如,等待I/O完成、申请缓冲区不能满足、等待信件(信号)等。

进程的状态转换:

进程的状态转换图


(1) 就绪→执行

处于就绪状态的进程,当进程调度程序为之分配了处理机后,该进程便由就绪状态转变成执行状态。

(2) 执行→就绪

处于执行状态的进程在其执行过程中,因分配给它的一个时间片已用完而不得不让出处理机,于是进程从执行状态转变成就绪状态。或者优先级更高的进程占用了CPU资源。

(3) 执行→阻塞

正在执行的进程因等待某种事件(或者说必要的系统资源)发生而无法继续执行时,便从执行状态变成阻塞状态。

(4) 阻塞→就绪

处于阻塞状态的进程,若其等待的事件已经发生,于是进程由阻塞状态转变为就绪状态

 

2、线程

线程的基本状态:就绪、阻塞、执行三中状态。其状态转换与进程类似,此处不再阐述。

要重点说明的是线程的阻塞状态

阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:

①  等待阻塞:运行的线程执行pthread_cond_wait()方法,系统将其放入等待队列;

②  同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用;

③  其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时;当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。

注:调用Sleepjoin时,不会释放所占用的资源,所以会进入阻塞状态;调用Wait时,会释放所占用的资源,所以会进入等待队列。

 

 

三、资源管理

1.      一个进程在创建时包括以下资源:

① 虚拟存储空间;该存储空间包括代码段、特点的进程数据,调用堆栈、堆栈(用于保存运行时运数中途产生的数据)。

②  分配给该进程的资源的操作系统描述符,诸如文件描述符Unix术语)或文件句柄Windows)、数据源和数据终端。

③  安全特性,诸如进程拥有者和进程的权限集(可以容许的操作)。

④  处理器状态(内文),诸如暂存器内容、物理存储器寻址等。当进程正在运行时,状态通常存储在暂存器,其他情况在存储器。

2.     一个进程中的线程共享的资源:

①  进程的代码段;

②  打开的文件描述符;

③  进程的当前目录;

④  进程用户ID、进程组ID;

⑤  进程的公有数据(信号量、互斥量等等);

3.     线程独有的资源有

①  线程ID

②  寄存器组;

③  线程的堆栈;

④  错误返回码;

⑤  线程的信号屏蔽码;

⑥  线程的优先级;

 

四、引入线程的原因

①  线程的调度比进程的调度代价小,同时创建线程比创建进程的代价低;

②  提高并发性,改善整个程序的吞吐量。在单个进程需要完成多个任务时,需要把任务串行化,有了多线程则可将相互独立的任务处理,为每个任务分配独立的线程即可,当然需要考虑数据同步和竞争问题。

③  一个进程的所有线程可以自动共享进程的资源,而在多进程中需使用系统的复杂机制才能实现内存、文件描述符的共享。

④  交互的程序同样可以利用多线程实现相应响应时间的改善,多线程可以把程序中的输入输出与其他处理部分分开。

⑤  充分发挥多处理器的功能。通过多线程设计,每个线程在一个处理器上运行,从而实现应用程序的并发性,改善每个处理器的利用率。

 

此外,补充一点关于进程切换的知识。

进行进程切换就是从正在运行的进程中收回处理器,然后再使待运行进程来占用处理器。所谓处理器回收,实质上就是把进程存放在处理器的寄存器中的中间数据找个地方存起来,从而把处理器的寄存器腾出来让其他进程使用。那么被中止运行进程的中间数据存在何处好呢?当然这个地方应该是进程的私有堆栈。

让进程来占用处理器,实质上是把某个进程存放在私有堆栈中寄存器的数据(前一次本进程被中止时的中间数据)再恢复到处理器的寄存器中去,并把待运行进程的断点送入处理器的程序指针PC,于是待运行进程就开始被处理器运行了,也就是这个进程已经占有处理器的使用权了。

例如:这就像多个同学要分时使用同一张课桌一样,所谓要收回正在使用课桌同学的课桌使用权,实质上就是让他把属于他的东西拿走;而赋予某个同学课桌使用权,只不过就是让他把他的东西放到课桌上罢了。

在切换时,一个进程存储在处理器各寄存器中的中间数据叫做进程的上下文,所以进程的切换实质上就是被中止运行进程与待运行进程上下文的切换。在进程未占用处理器时,进程的上下文是存储在进程的私有堆栈中的。

与进程切换不同,线程的切换开销则小很多,只需要保存和恢复线程的寄存器内存,栈的切换也是通过寄存器的切换来完成的。可见,线程的切换比进程的切换代价要低很多。

 

参考文献:

[1]      http://www.tantengvip.com/2011/10/state/.

[2]      http://zh.wikipedia.org/wiki/%E8%BF%9B%E7%A8%8B#.E7.8B.80.E6.85.8B.

[3]      http://zh.wikipedia.org/wiki/%E5%9F%B7%E8%A1%8C%E7%B7%92.

[4]      Tanenbaum A S, 坦尼鲍姆,向群,.现代操作系统[M].机械工业出版社, 2005..

[5]      http://uule.iteye.com/blog/1100799.

0 0
原创粉丝点击