计算机操作系统之线程(四)

来源:互联网 发布:虚拟机linux 连接电脑 编辑:程序博客网 时间:2024/05/18 09:21

1.线程的定义

在讲述线程的定义之前,我们要了解 为什莫要产生线程?
线程的产生 是为了进一步提高 系统的并发性。其主要原因是为了节约操作系统额外的开销。
进程的引入可以实现并行计算,线程的引入可以进一步提高系统的并发性。一个进程可以拥有多个线程,这些线程共享同一地址空间,他不拥有系统资源,且只需要很少在运行时必不可少的硬件,因此线程在创建,撤销,切换等环节所需要的时空开销比进程要少的多。

2.线程和进程的比较

2.1调度分派:线程作为调度和分派的基本单位,而进程作为资源拥有的基本单位。同一进程中,线程的切换不会引起进程的切换,但从一个进程中的线程切换到另外一个进程中的线程时,将会引起进程切换。
2.2 资源拥有:线程一般不拥有资源(除少量必不可少的系统资源),但它可以访问其隶属的进程的资源,即一个进程的代码段,数据段以及拥有的系统资源,如已打开的文件、I/O设备等。
2.3地址空间:不同进程的地址空间是相互独立的,同一进程的各线程共享同一地址空间。一个进程可以拥有多个线程,反过来不行。
2.4通信关系:进程间的通信需要使用系统的通信机制,同一进程中的各线程可以通过直接读写数据段(如全局变量)来进行通信。
2.5系统开销:在创建和撤销进程时,系统都要为之创建和回收进程控制块,分配或回收资源,操作系统付出的开销明显大于线程创建或撤销时的开销,在进程切换时,涉及到当前进程CPU环境的保存和新被调度运行进程的CPU环境的设置,而线程的切换则仅需保存和设置少量寄存器内容,不涉及存储器管理方面的操作,所以线程的切换开销远小于进程切换开销,以外,由于一个进程中的多个线程具有相同的地址空间,在同步和通信的实现上也比较容易,在一些操作系统中,线程的切换,同步和通信都无需操作系统内核的干预。

3.线程的属性

3.1轻型实体,每个线程都具有一个用于控制线程运行的线程控制块TCB,用于指示被执行指令序列的程序计数器,保留局部变量,少量状态参数合返回地址等。
3.2 独立调度和分派的基本单位,线程是能独立运行的基本单位,切换非常迅速且开销小。
3.3可并发执行,一个进程、不同进程的线程均可并发执行。
3.4 共享进程资源,同一进程中的线程共享该进程所拥有的资源,所有线程拥有相同的地址空间(进程的地址空间),这意味着线程可以访问该地址空间中的每一个虚地址,此外,还可以访问进程所拥有的已打开文件,定时器,信号量机构等。

4.线程的状态

4.1 状态参数:每一个线程可利用线程标识符和一组状态参数进行描述。状态参数包括寄存器状态(包括程序计数器和堆栈指针中的内容)、堆栈(保存的局部变量和返回地址)、线程运行状态、优先级、线程专有存储器(保存线程自己的具有变量拷贝)、信号屏蔽(对某些信息加以屏蔽)。
4.2线程运行状态:运行状态包括就绪状态、执行状态、阻塞状态。注意:线程一般没有挂起状态。而且线程共享该存在的进程的状态。

5.线程的操作

5.1派生(SPawn)
在创建新线程时,需要利用一个线程创建函数(或系统调用),并根据相应的参数,如指向线程主程序的入口指针、堆栈的大小、调度的优先级等。在线程创建函数执行完后,将返回一个线程标识符供以后使用。
5.2阻塞(Block) 5.3解除阻塞(Unblock)
5.4结束(Finish)
结束线程的方式有两种,线程完成工作后自愿退出或者线程在运行中出现错误或由于某种原因而被其他线程强行终止。在大多数OS中,线程被终止后并不立即释放它所占有的资源,只有当进程中的其他线程执行了分离函数后,被终止的线程才与资源分离,此时的资源才能被其他线程利用。虽然已被终止但尚未释放资源的线程,仍可以被需要它的线程所调用,以使被终止线程重新恢复运行。

6.线程的控制(同步、通信)

6.1互斥锁:互斥锁是一种比较简单的、用于实现线程间对资源互斥访问的机制。由于操作互斥锁的时间和空间开销较低,因为较适合高频度使用的关键共享数据和程序段。
6.2条件变量:创建一个互斥锁时便联系着一个条件变量,单纯的互斥锁用于短期锁定,主要用来保证对临界区的互斥进入,条件变量则用于线程的长期等待,直至所等待的资源成为可用的资源。
6.4 计数信号量机制:包括私有信号量(同一进程的不同线程需要同步时,可调用创建信号量的命令来创建私有信号量,其数据结构存放在应用程序的地址空间中,私有信号量属于特定的进程所有,OS并不知道私有信号量的存在,当发生私有信号量的占用者异常或正常结束,但并未释放私有信号量所占有的空间的情况时,系统将无法使它恢复为0,也不能将它传送到下一个请求它的线程),公用信号量(其实现不同进程间或不同进程中各线程之间的同步而设置,由所有进程使用,其数据结构放在手保护的系统存储区中,由OS为它分配空间并进行管理,也称为系统信号量,OS会自动回收其空间,其是一种比较安全的同步机制)

7.线程的类型

7.1内核支持线程
定义:在内核的支持下运行的,即无论是用户进程中的线程,还是系统进程中的线程,他们的创建、撤销和切换等,是依靠内核实现的。此处,在内核空间还为每一个线程设置了一个线程控制块,内核是根据该控制块而感知线程的存在的,并对其加以控制。
实现原理:系统在创建一个新进程时,便为它分配一个任务数据区PTAD(Per Task Data Area),其中包括若干个线程控制块TCB空间,其保存在内核空间中。当进程要创建一个新线程时,便为其分配一个TCB,填入相关的信息,分配必要的资源,于是新创建的线程便有机会执行。当PTAD中的所有TCB分配完后,进程又要创建新的线程时,只要其所创建的线程数量未超过系统的允许值是,系统可再为之分配新的TCB空间。在撤销一个线程时,也回收该线程的所有资源和TCB,有的系统为了减少创建和撤销一个线程时的开销,在撤销一个线程时,并不立即回收该线程的资源和TCB,当以后要创建一个新线程时,便可利用已被撤销但仍保持有资源和TCB的线程作为新线程。
7.2用户级线程的实现
定义:此线程仅存在于用户空间中,对于这种线程的创建、撤销、线程之间的同步与通信等功能,都无须利用系统调用来实现。对于用户级线程的切换,通常是发生在一个应用进程的诸多线程之间,这时,也同样无须内核的支持。切换规则简单且快。
值得说明的是:对于设置了用户级线程的系统,其调度是以进程为单位的。所以在采用轮转调度算法时,各个进程轮流执行一个时间片,这对诸进程而言,看似公平, 其实不然。对于进程中的线程是不公平的,一个进程A有一个用户级线程,而另一个进程B有100个线程,所以A中的线程的运行时间,是B进程中的各线程运行时间的100倍
实现原理:用户级线程是在用户空间实现的,所有的用户级线程都具有相同的结构,他们都运行在一个中间系统上面,当前有两种方式实现中间系统,即运行时系统和内核控制线程。
运行时系统是用于管理和控制线程的函数(过程)的集合,其中包括用于创建和撤销线程的函数、线程同步和通信的函数以及实现线程调度的函数等,正因为有了这些函数,才使得用户级线程与内核无关,运行时系统中的所有函数都驻留在用户空间,并作为用户级线程与内核之间的接口。用户级线程在切换时不需要转入核心态,而是由运行时系统中的线程切换过程来执行切换任务。
内核控制线程又称为轻型进程LWP(Light Weight Process),每一个进程都可拥有多个LWP,同用户级线程一样,每个LWP都有自己的数据结构(如TCB),其中包括线程标识符,优先级,状态、栈、局部存储区等。它们也可以享受进程所拥有的资源,LWP可通过系统调用来获得内核提供的服务,当一个用户级线程运行时,只要将它连接到一个LWP上,此时它便具有了内核提供支持线程的所有属性,这种线程实现方式就是组合方式。LWP会做成一个缓冲池,用户级线程都可以连接到任何一个LWP上,为了使每一用户级线程都能利用LWP与内核通信,可以使多个用户级线程多路复用一个LWP,但只有当前连接到LWP上的线程才能与内核通信,其余进程或者阻塞,或者等待LWP,每一个LWP也需要连接到一个内核级线程上,这样,通过LWP可把用户级线程与内核线程连接起来,用户级线程可通过LWP来访问内核,内核看不到用户级线程,LWP实现了内核与用户级线程的隔离。

7.3 用户线程和内核线程的对应关系
7.3.1. 一对一模型:为每一个用户线程都设置一个内核控制线程与之连接,当一个线程阻塞时,允许调度另一个线程运行,在多处理机系统中,则有多个线程并行执行。
7.3.2. 多对一模型:将多个用户线程映射到一个内核控制线程,为了管理方便,这些用户线程一般属于一个进程,运行在该进程的用户空间,对这些线程的调度和管理也是在该进程的用户空间完成的,当用户线程需要访问内核时,才将其映射到一个内核控制线程上,但每次只允许一个线程进行映射。 线程管理开销小,效率高,但当一个线程在访问内核时发生阻塞,则整个进程都会被阻塞,并且在多处理机系统中,一个进程的多个线程无法实现并行。
7.3.3. 多对多模型:将多个用户线程映射到多个内核控制线程,内核控制线程的数目可以根据应用进程和系统的不同而变化。
注意:当既允许多对多模型也允许一个用户线程绑定到内核线程,称为二级模型。

8.线程中的一些注意点:
1.java的thread.join();等待子线程结束。
2.多线程一起完成任务时,如果一个线程已经完成了目标,则其他线程可以被取消;或者当用户想要取消线程时,则会被取消。要取消的线程为目标线程。
3.异步取消:立即终止。延迟取消:每次取消之前都要查看是否应该被取消。(这个好)
4.信号由特定事件发生,并且信号只能被处理一次。信号是由内核或进程发送的。信号是进程间通信的一种方式,一个特定的信号是一个整数。
5.当单线程时,只要把信号发送给进程。不用考虑选择哪个线程发送。
当多线程时,需要考虑发给每个线程还是产生事件的线程,还是一个规定接受信号的线程。
6.同步信号:信号发送给产生信号的进程。信号发送给特定的产生信号的线程。
异步信号:发送给其他进程不相关的进程。比如终止进程。
对于信号处理,可以按照默认信号处理程序,也可以按照用户特定信号处理程序。

0 0