码迷,mamicode.com
首页 > 编程语言 > 详细

线程与进程的区别

时间:2015-04-13 14:48:30      阅读:185      评论:0      收藏:0      [点我收藏+]

标签:系统   线程   并发   调度   属性   

线程的基本概念

线程的引入

  如果说,在操作系统中引入进程的目的,是为了使多个程序能并发执行,以提高资源利用率和系统吞吐量,那么,在操作系统中再引入线程,则是为了减少程序在并发执行时所付出的时空开销,使 OS具有更好的并发性。为了说明这一点,我们首先来回顾进程的两个基本属性:
  ① 进程是一个可拥有资源的独立单位;
  ② 进程同时又是一个可独立调度和分派的基本单位。正是由于进程有这两个基本属性,才使之成为一个能独立运行的基本单位从而也就构成了进程并发执行的基础。
  
  然而,为使程序能并发执行,系统还必须进行以下的一系列操作。 
1) 创建进程
  系统在创建一个进程时,必须为它分配其所必需的、除处理机以外的所有资源,如内存空间、I/O 设备,以及建立相应的PCB。
2) 撤消进程
  系统在撤消进程时,又必须先对其所占有的资源执行回收操作,然后再撤消PCB。
3) 进程切换
  对进程进行切换时,由于要保留当前进程的CPU环境和设置新选中进程的CPU环境,因而须花费不少的处理机时间。
  
  换言之,由于进程是一个资源的拥有者,因而在创建、撤消和切换中,系统必须为之付出较大的时空开销。正因如此,在系统中所设置的进程,其数目不宜过多,进程切换的频率也不宜过高,这也就限制了并发程度的进一步提高。
  
  如何能使多个程序更好地并发执行同时又尽量减少系统的开销,已成为近年来设计操作系统时所追求的重要目标。有不少研究操作系统的学者们想到,若能将进程的上述两个属性分开,由操作系统分开处理,亦即对于作为调度和分派的基本单位,不同时作为拥有资源的单位,以做到“轻装上阵” ;而对于拥有资源的基本单位,又不对之进行频繁的切换。正是在这种思想的指导下,形成了线程的概念。
  
  随着 VLSI 技术和计算机体系结构的发展,出现了对称多处理机(SMP)计算机系统。它为提高计算机的运行速度和系统吞吐量提供了良好的硬件基础。但要使多个CPU很好地协调运行,充分发挥它们的并行处理能力,以提高系统性能,还必须配置性能良好的多处理机 OS。但利用传统的进程概念和设计方法,已难以设计出适合于 SMP 结构的计算机系统的 OS。这是因为进程“太重” ,致使实现多处理机环境下的进程调度、分派和切换时,都需花费较大的时间和空间开销。 如果在OS中引入线程,以线程作为调度和分派的基本单位,则可以有效地改善多处理机系统的性能。因此,一些主要的OS(UNIX、OS/2、Windows)厂家都又进一步对线程技术做了开发,使之适用于 SMP的计算机系统。

线程与进程的比较

  线程具有许多传统进程所具有的特征,所以又称为轻型进程(Light-Weight Process)或进程元,相应地把传统进程称为重型进程(Heavy-Weight Process),传统进程相当于只有一个线程的任务。在引入了线程的操作系统中,通常一个进程都拥有若干个线程,至少也有一个线程。下面我们从调度性、并发性、系统开销和拥有资源等方面对线程和进程进行比较。

  • 调度
    在传统的操作系统中,作为拥有资源的基本单位和独立调度、分派的基本单位都是进程。而在引入线程的操作系统中,则把线程作为调度和分派的基本单位,而进程作为资源拥有的基本单位,把传统进程的两个属性分开,使线程基本上不拥有资源,这样线程便能轻装前进,从而可显著地提高系统的并发程度。在同一进程中,线程的切换不会引起进程的切换,但从一个进程中的线程切换到另一个进程中的线程时,将会引起进程的切换。

  • 并发性
    在引入线程的操作系统中,不仅进程之间可以并发执行,而且在一个进程中的多个线程之间亦可并发执行,使得操作系统具有更好的并发性,从而能更加有效地提高系统资源的利用率和系统的吞吐量。例如,在一个未引入线程的单CPU操作系统中,若仅设置一个文件服务进程,当该进程由于某种原因而被阻塞时,便没有其它的文件服务进程来提供服务。在引入线程的操作系统中,则可以在一个文件服务进程中设置多个服务线程。当第一个线程等待时,文件服务进程中的第二个线程可以继续运行,以提供文件服务;当第二个线程阻塞时,则可由第三个继续执行,提供服务。显然,这样的方法可以显著地提高文件服务的质量和系统的吞吐量。

  • 拥有资源
    不论是传统的操作系统,还是引入了线程的操作系统,进程都可以拥有资源,是系统中拥有资源的一个基本单位。一般而言,线程自己不拥有系统资源(也有一点必不可少的资源),但它可以访问其隶属进程的资源,即一个进程的代码段、数据段及所拥有的系统资源,如已打开的文件、I/O 设备等,可以供该进程中的所有线程所共享。

  • 系统开销
    在创建或撤消进程时,系统都要为之创建和回收进程控制块,分配或回收资源,如内存空间和I/O设备等,操作系统所付出的开销明显大于线程创建或撤消时的开销。类似地,在进程切换时,涉及到当前进程CPU环境的保存及新被调度运行进程的CPU环境的设置,而线程的切换则仅需保存和设置少量寄存器内容,不涉及存储器管理方面的操作,所以就切换代价而言,进程也是远高于线程的。此外,由于一个进程中的多个线程具有相同的地址空间,在同步和通信的实现方面线程也比进程容易。在一些操作系统中,线程的切换、同步和通信都无须操作系统内核的干预。

多线程OS中的进程

  在多线程OS中,进程是作为拥有系统资源的基本单位,通常的进程都包含多个线程并为它们提供资源,但此时的进程就不再作为一个执行的实体。多线程 OS 中的进程有以下属性:

  • 作为系统资源分配的单位。在多线程OS中,仍是将进程作为系统资源分配的基本单位,在任一进程中所拥有的资源包括受到分别保护的用户地址空间、用于实现进程间和线程间同步和通信的机制、已打开的文件和已申请到的 I/O 设备,以及一张由核心进程维护的地址映射表,该表用于实现用户程序的逻辑地址到其内存物理地址的映射。

  • 可包括多个线程。通常,一个进程都含有多个相对独立的线程,其数目可多可少,但至少也要有一个线程,由进程为这些(个)线程提供资源及运行环境,使这些线程可并发执行。在OS中的所有线程都只能属于某一个特定进程。

  • 进程不是一个可执行的实体。 在多线程OS中,是把线程作为独立运行的基本单位,所以此时的进程已不再是一个可执行的实体。虽然如此,进程仍具有与执行相关的状态。例如,所谓进程处于“执行”状态,实际上是指该进程中的某线程正在执行。此外,对进程所施加的与进程状态有关的操作,也对其线程起作用。例如,在把某个进程挂起时,该进程中的所有线程也都将被挂起;又如,在把某进程激活时,属于该进程的所有线程也都将被激活。

线程间的同步和通信

互斥锁(mutex)

  互斥锁是一种比较简单的、用于实现线程间对资源互斥访问的机制。由于操作互斥锁的时间和空间开销都较低,因而较适合于高频度使用的关键共享数据和程序段。互斥锁可以有两种状态,即开锁(unlock)和关锁(lock)状态。相应地,可用两条命令(函数)对互斥锁进行操作。其中的关锁lock操作用于将 mutex关上,开锁操作 unlock则用于打开 mutex。

  当一个线程需要读/写一个共享数据段时,线程首先应为该数据段所设置的 mutex 执行关锁命令。命令首先判别 mutex 的状态,如果它已处于关锁状态,则试图访问该数据段的线程将被阻塞;而如果 mutex 是处于开锁状态,则将 mutex 关上后便去读/写该数据段。在线程完成对数据的读/写后,必须再发出开锁命令将 mutex 打开,同时还须将阻塞在该互斥锁上的一个线程唤醒,其它的线程仍被阻塞在等待mutex打开的队列上。

  另外,为了减少线程被阻塞的机会,在有的系统中还提供了一种用于 mutex 上的操作命令 Trylock。当一个线程在利用 Trylock 命令去访问 mutex 时,若 mutex 处于开锁状态,Trylock 将返回一个指示成功的状态码;反之,若 mutex 处于关锁状态,则 Trylock 并不会阻塞该线程,而只是返回一个指示操作失败的状态码。

条件变量

  在许多情况下,只利用 mutex 来实现互斥访问可能会引起死锁,我们通过一个例子来说明这一点。有一个线程在对mutex 1 执行关锁操作成功后,便进入一临界区 C,若在临界区内该线程又须访问某个临界资源R,同样也为R设置另一互斥锁 mutex 2。假如资源 R此时正处于忙碌状态,线程在对mutex 2执行关锁操作后必将被阻塞,这样将使mutex 1一直保持关锁状态;如果保持了资源 R的线程也要求进入临界区 C,但由于 mutex 1一直保持关锁状态而无法进入临界区,这样便形成了死锁。为了解决这个问题便引入了条件变量。

  每一个条件变量通常都与一个互斥锁一起使用,亦即,在创建一个互斥锁时便联系着一个条件变量。单纯的互斥锁用于短期锁定,主要是用来保证对临界区的互斥进入。而条件变量则用于线程的长期等待,直至所等待的资源成为可用的资源。

  现在, 我们看看如何利用互斥锁和条件变量来实现对资源 R的访问。 线程首先对mutex执行关锁操作,若成功便进入临界区,然后查找用于描述该资源状态的数据结构,以了解资源的情况。只要发现所需资源 R 正处于忙碌状态,线程便转为等待状态,并对 mutex 执行开锁操作后,等待该资源被释放;若资源处于空闲状态,表明线程可以使用该资源,于是将该资源设置为忙碌状态,再对 mutex 执行开锁操作。下面给出了对上述资源的申请(左半部分)和释放(右半部分)操作的描述。

   Lock mutex                     Lock mutex 
     check data structures;                 mark resource as free; 
     while(resource busy);                unlock mutex; 
       wait(condition variable);         wakeup(condition variable); 
     mark resource as busy; 

  原来占有资源R的线程在使用完该资源后,便按照右半部分的描述释放该资源,其中的wakeup(condition variable)表示去唤醒在指定条件变量上等待的一个或多个线程。在大多数情况下,由于所释放的是临界资源,此时所唤醒的只能是在条件变量上等待的某一个线程,其它线程仍继续在该队列上等待。但如果线程所释放的是一个数据文件,该文件允许多个线程同时对它执行读操作。在这种情况下,当一个写线程完成写操作并释放该文件后,如果此时在该条件变量上还有多个读线程在等待,则该线程可以唤醒所有的等待线程。

信号量机制

  前面所介绍的用于实现进程同步的最常用工具——信号量机制,也可用于多线程 OS中,实现诸线程或进程之间的同步。为了提高效率,可为线程和进程分别设置相应的信 号量。
  
1) 私用信号量(private samephore)
  当某线程需利用信号量来实现同一进程中各线程之间的同步时,可调用创建信号量的命令来创建一私用信号量,其数据结构存放在应用程序的地址空间中。私用信号量属于特定的进程所有,OS并不知道私用信号量的存在,因此,一旦发生私用信号量的占用者异常结束或正常结束, 但并未释放该信号量所占有空间的情况时,系统将无法使它恢复为0(空),也不能将它传送给下一个请求它的线程。
  
2) 公用信号量(public semaphort)
  公用信号量是为实现不同进程间或不同进程中各线程之间的同步而设置的。由于它有着一个公开的名字供所有的进程使用,故而把它称为公用信号量。其数据结构是存放在受保护的系统存储区中,由OS为它分配空间并进行管理,故也称为系统信号量。如果信号量的占有者在结束时未释放该公用信号量,则 OS会自动将该信号量空间回收,并通知下一进程。可见,公用信号量是一种比较安全的同步机制。

线程与进程的区别

标签:系统   线程   并发   调度   属性   

原文地址:http://blog.csdn.net/u014539401/article/details/45023779

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!