线程概述

来源:百度文库 编辑:16楼社区 时间:2021/04/15 21:39:02

4.9 线程(Thread)

引入线程的目的是简化线程间的通信,以小的开销来提高进程的并发程度。


4.9.1 线程的概念

  
线程 有时称轻量级进程。 进程中的一个运行实体,是一个CPU调度单位, 资源的拥有者还是进程或称任务

   事实上,引入线程主要是为了提高系统的执行效率,减少处理机的空转时间和调度切换(保护现场信息)的时间,以及便于系统管理。
  

             
      进程与线程之间关系
   进程和线程的比较 进程是资源分配的基本单位。所有与该进程有关的资源,都被记录在进程控制块PCB中。以表示该进程拥有这些资源或正在使用它们。另外,进程也是抢占处理机的调度单位,它拥有一个完整的虚拟地址空间。与进程相对应,线程与资源分配无关,它属于某一个进程,并与进程内的其他线程一起共享进程的资源。

   当进程发生调度时,不同的进程拥有不同的虚拟地址空间,而同一进程内的不同线程共享同一地址空间。

   线程只由相关堆栈(系统栈或用户栈)寄存器和线程控制表TCB组成。寄存器可被用来存储线程内的局部变量,但不能存储其他线程的相关变量。

   发生进程切换与发生线程切换时相比较,进程切换时涉及到有关资源指针的保存以及地址空间的变化等问题;线程切换时,由于同不进程内的线程共享资源和地址 空间,将不涉及资源信息的保存和地址变化问题,从而减少了操作系统的开销时间。而且,进程的调度与切换都是由操作系统内核完成,而线程则既可由操作系统内 核完成,也可由用户程序进行。

               
                    图   多线程与进程之间的关系

 4.9.2 线程的适用范围

    典型的应用

     1.服务器中的文件管理或通信控制

     2.前后台处理

     3.异步处理

                       

4.9.3 线程的执行特性

 
线程有3个基本状态:执行、就绪、阻塞

  线程有5种基本操作:

 派生:线程在进程内派生出来,它即可由进程派生,也可由线程派生。 阻塞(Block):如果一个线程在执行过程中需要等待某个事件发生,则被阻塞。 激活(unblock):如果阻塞线程的事件发生,则该线程被激活并进入就绪队列。 调度(schedule):选择一个就绪线程进入执行状态。 结束(Finish):如果一个线程执行结束,它的寄存器上下文以及堆栈内容等将被释放。
            
     图  线程的状态与操作
线程的另一个执行特性是同步。线程中所使用的同步控制机制与进程中所使用的同步控制机制相同。

4.9.4 线程的分类

  
线程有两个基本类型:

     用户级线程:管理过程全部由用户程序完成,操作系统内核心只对进程进行管理。

     系统级线程(核心级线程):由操作系统内核进行管理。操作系统内核给应用程序提供相应的系统调用和应用程序接口API,以使用户程序可以创建、执行、撤消线程。

线程举例

1. SUN Solaris 2.3

   ²        Solaris支持内核线程、轻权进程和用户线程。一个进程可有大量用户线程;大量用户线程复用少量的轻权进程,轻权进程与内核线程一一对应。
 ¨
         用户级线程在调用核心服务时(如文件读写),需要“捆绑(bound)”在一个LWP上。永久捆绑(一个LWP固定被一个用户级线程占用,该LWP移到LWP池之外)和临时捆绑(从LWP池中临时分配一个未被占用的LWP)。
 
²        在调用系统服务时,如果所有LWP已被其他用户级线程所占用(捆绑),则该线程阻塞直到有可用的LWP
 
²        如果LWP执行系统线程时阻塞(如read()调用),则当前捆绑在LWP上的用户级线程也阻塞。
                                  
                               图  用户线程、轻权进程和核心线程的关系

 ¨
       
有关的C库函数
        /* 创建用户级线程             */
    int
thr_create(void *stack_base, size_t stack_size,
    void *(*start_routine)(void *), void *arg, long flags,
    thread_t *new_thread_id); 
  其中flags包括:THR_BOUND(永久捆绑), THR_NEW_LWP(创建新LWP放入LWP池),若两者同时指定则创建两个新LWP,一个永久捆绑而另一个放入LWP池。
 ²        有关的系统调用
   /*
在当前进程中创建LWP     */
  int _lwp_create(ucontext_t *contextp, unsigned long flags,

  lwpid_t *new_lwp_id);
  /*
构造LWP上下文          */
  void _lwp_makecontext(ucontext_t *ucp,
   void (*start_routine)( void *), void *arg,
  void *private, caddr_t stack_base, size_t stack_size);
  /*
注意:没有进行“捆绑”操作的系统调用 */

    2. Windows NT

   ²        NT线程的上下文包括:寄存器、核心栈、线程环境块和用户栈。
 ²        NT线程状态
   (1)         就绪状态:进程已获得除处理机外的所需资源,等待执行。
   (2)
         备用状态:特定处理器的执行对象,系统中每个处理器上只能有一个处于备用状态的线程。
 
(3)         运行状态:完成描述表切换,线程进入运行状态,直到内核抢先、时间片用完、线程终止或进行等待状态。
 
(4)         等待状态:线程等待对象句柄,以同步它的执行。等待结束时,根据优先级进入运行、就绪状态。
 
(5)         转换状态:线程在准备执行而其内核堆栈处于外存时,线程进入转换状态;当其内核堆栈调回内存,线程进入就绪状态。
 
(6)         终止状态:线程执行完就进入终止状态;如执行体有一指向线程对象的指针,可将线程对象重新初始化,并再次使用。

  

                          图  Windows NT的线程状态
  ²        NT线程的有关API
   
            CreateThread()函数在调用进程的地址空间上创建一个线程,以执行指定的函数;返回值为所创建线程的句柄。
          ExitThread()函数用于结束本线程。
          SuspendThread()函数用于挂起指定的线程。
          ResumeThread()函数递减指定线程的挂起计数,挂起计数为0时,线程恢复执行。