2.7 线 程
2.7.1 线程的基本概念
1.线程的引入
在操作系统中再引入线程,是为了减少程序在并发执行时所付出的时空开销,使OS具有更好的并发性。
2.线程与进程的比较
1) 调度
传统操作系统:拥有资源的基本单位和独立调度、分派的基本单位都是进程。
引入线程的操作系统:线程作为调度和分派的基本单位。
2) 并发性
引入线程的操作系统:进程之间可以并发执行,一个进程中的多个线程之间亦可并发执行。从而有效地提高系统资源的利用率和系统的吞吐量。
3) 拥有资源
传统的操作系统/基于线程的操作系统:进程是系统中拥有资源的基本单位。
线程自己不拥有系统资源可以访问其隶属进程的资源。
4) 系统开销
进程:在创建或撤消进程、进程切换时,操作系统需要分配内存空间,PCB,保留CPU当前状态等,所付出的开销大。
线程:其切换则仅需保存和设置少量寄存器内容,不涉及存储器管理方面的操作。一个进程中的多个线程具有相同的地址空间,在同步和通信的实现方面线程也比进程容易。
3.线程的属性
线程是利用CPU的基本单位,是花费最小开销的实体。
(1) 轻型实体。线程中的实体基本上不拥有系统资源,只是有一点必不可少的、能保证其独立运行的资源,比如TCB、程序计数器、一组寄存器和堆栈。
(2) 独立调度和分派的基本单位。
(3) 可并发执行。在一个进程中的多个线程之间可以并发执行;不同进程中的线程也能并发执行。
(4) 共享进程资源。
4.线程的状态
(1) 状态参数。
①寄存器状态,它包括程序计数器PC
和堆栈指针中的内容;
②堆栈,在堆栈中通常保存有局部变
量和返回地址;
③线程运行状态,
④优先级
⑤线程专有存储器
(2) 线程运行状态。
①执行状态;②就绪状态;③阻塞状态;
5.线程的创建和终止
线程具有生命期。
线程终止:自愿退出;强行终止。
已被终止但尚未释放资源的线程仍可以被其它线程利用“等待线程终止”的连接命令所调用。从而使线程重新运行。
6.多线程OS中的进程
多线程OS中的进程有以下属性:
(1) 作为系统资源分配的单位。
(2) 可包括多个线程。
(3) 进程不是一个可执行的实体。
但进程仍具有与执行相关的状态。
与进程状态有关的操作,也对其线程起作用。例如,在把某个进程挂起时,该进程中的所有线程也都将被挂起。
2.6.2线程间的同步和通信
1.互斥锁(mutex)
互斥锁只是个标识符而不是信号量。用于线程需要读/写同一个共享数据段时。互斥锁可以有两种状态,即开锁(unlock)和关锁(lock)状态。
2.条件变量
在许多情况下,只利用mutex来实现互斥访问可能会引起死锁,为了解决这个问题便引入了条件变量。
每一个条件变量通常都与一个互斥锁一起使用。单纯的互斥锁用于短期锁定。而条件变量则用于线程的长期等待,直至所等待的资源成为可用的资源。
不论有无线程访问临资,上来先关锁,进入临界区再判断资源状态,忙则阻塞在条件变量上,闲则执行,两种情况都要把锁打开。
3.信号量机制
1) 私用信号量(privatesamephore)
同一进程中各线程之间的同步时创建私用信号量,属于特定的进程所有,OS并不知道私用信号量的存在。
2) 公用信号量(publicsemaphort)
公用信号量是为实现不同进程间或不同进程中各线程之间的同步而设置的。也称为系统信号量。如果信号量的占有者在结束时未释放该公用信号量,则OS会自动将该信号量空间回收,并通知下一进程。可见,公用信号量是一种比较安全的同步机制。
2.8 线程的实现方式
1.内核支持线程KST
无论是用户进程中的线程,还是系统进程中的线程,其创建、撤消和切换等都是依靠内核在内核空间实现的。内核根据该控制块TCB而感知某线程的存在,并对其加以控制。
这种线程实现方式优点:
(1) 在多处理器系统中,内核能够同时调度同一进程中多个线程并行执行;
(2) 如果进程中的一个线程被阻塞了,内核可以调度该进程中的其它线程占有处理器运行,也可以运行其它进程中的线程;
(3) 内核支持线程具有很小的数据结构和堆栈,线程的切换比较快,切换开销小;
(4) 内核本身也可以采用多线程技术,可以提高系统的执行速度和效率。
内核支持线程的主要缺点是:对于用户的线程切换而言,其模式切换的开销较大,需要从用户态转到内核态进行。
2.用户级线程ULT
线程仅存在于用户空间中其创建、撤消、同步与通信等功能,都无须利用系统调用来实现。线程是与内核无关,内核完全不知道用户级线程的存在。
优点:
(1) 线程切换不需要转换到内核空间节省了模式切换的开销。
(2) 调度算法可以是进程专用的。
(3) 用户级线程的实现与操作系统平台无关,因此,用户级线程甚至可以在不支持线程机制的操作系统平台上实现。
缺点:
(1) 系统调用的阻塞问题。进程阻塞,进程内的所有线程都会被阻塞。
(2) 多线程应用不能利用多处理机进行并行执行。
3.组合方式ULT/KST
内核支持多KST线程的建立、调度和管理,同时,也允许用户应用程序建立、调度和管理用户级线程。
2.8.2 线程的实现
1.内核支持线程的实现
系统在创建一个新进程时,便分配一个任务数据区PTDA(PerTask Data Area),其中包括若干个线程控制块TCB空间,如图2-15所示。TCB中的信息保存在内核空间中。
内核支持线程的创建、撤消均与进程的相类似。在有的系统中为了减少创建和撤消一个线程时的开销,在撤消一个线程时,并不立即回收该线程的资源和TCB,当以后再要创建一个新线程时,便可直接利用已被撤消但仍保持有资源和TCB的线程作为新线程。
内核支持线程的调度和切换与进程的调度和切换十分相似,也分抢占式方式和非抢占方式两种。
2.用户级线程的实现
用户级线程是在用户空间实现的,运行在一个中间系统的上面。当前有两种方式实现的中间系统,即运行时系统和内核控制线程。
1) 运行时系统(RuntimeSystem)
所谓“运行时系统”,即线程库是用于管理和控制线程的函数(过程)的集合,包括用于创建和撤消线程的函数、线程同步和通信的函数以及实现线程调度的函数等。是用户级线程与内核之间的接口。
2) 内核控制线程/轻型进程LWP
LWP由用户进程调用函数创建,内核识别,可通过系统调用来获得内核提供的服务。
当一个用户级线程运行时,只要将它连接到一个LWP上,此时它便具有了内核支持线程的所有属性。
这种线程实现方式实质上是组合方式。
用户级线程可通过LWP来访问内核,但内核所看到的总是多个LWP而看不到用户级线程。即LWP实现了在内核与用户级线程之间的隔离,从而使用户级线程与内核无关。
当用户级线程要通信时需借助于LWP,而且每个要通信的用户级线程都需要一个LWP。
3.用户级线程与内核控制线程的连接
1) 一对一模型
一个内核控制线程一个用户线程。
该模型并行能力较强。
2)一对多模型
一个内核控制线程连多个用户线程。
多个用户线程一般属于一个进程。
优点:线程管理的开销小,效率高。
缺点:一个进程的多个线程无法实现并行。
3) 多对多模型
综合上述两种模型的优点,将多个用户线程映射到多个内核控制线程。