线程与SMP

来源:互联网 发布:php企业门户网站模板 编辑:程序博客网 时间:2024/06/16 17:16

1.系统调用

       操作系统的主要功能是为应用程序的运行创建良好的环境,为了达到这个目的,内核提供一系列具备预定功能的多内核函数,通过一组称为系统调用(system call)的接口呈现给用户。系统调用把应用程序的请求传给内核,调用相应的的内核函数完成所需的处理,将处理结果返回给应用程序,如果没有系统调用和内核函数,用户将不能编写大型应用程序。

 

2.操作系统分派调度的单位是线程,而资源所有权的单位是进程。

       下面是单线程和多线程的模型图。

       进程中的所有线程共享进程的状态和资源,它们驻留在同一块地址空间中,并且可以访问到相同的数据。当一个线程改变了内存中的一个数据时,其他线程在访问这一数据项时能够看到变化后的结果。由此带来很多效率上的提升,同时也引出些多线程方面的问题。

       在性能上线程的优点有:

1)在一个进程中创建一个线程,比重新创建一个进程的时间少许多。

2)终止一个线程比种植一个进程花费的时间少。

3)同一进程内线程间切换比进程键切换花费的时间少。

4)线程提高了不同的执行程序间通信效率。在大多数系统中,进程间的通信需要内核的介入,以提供保护和通信所需要的机制。由于线程共享资源,所以无需调用内核就可以相互通信。

思考1-3点的原因。

 

3.用户级和内核级线程

3.1用户级线程

       在一个纯粹的用户级线程软件中,有关线程管理的所有工作都由应用程序完成,内核意识不到线程的存在。

       任何应用程序都可以通过使用线程库被设计成多线程程序。线程库是用于用户级线程管理的一个例程包,它包含用于创建和销毁线程的代码、在线程间传递数据和消息的代码、调度线程执行的代码以及保存和恢复线程上下文的代码。

       所以线程的创建,消息传递,调度,保存/恢复上下文都有线程库来完成。内核并不知道这些活动。内核继续以进程为调度单位,并且给该进程指定一个执行状态(就绪、运行、阻塞等)。

        但是由线程库管理线程而由内核调度进程,并且系统调用(许多都会引起阻塞,而阻塞必须要内核启动)由操作系统核心提供,运行于核心态。所以会出现一些问题,如下图。

a)初始状态

b)线程2进行系统调用,直接阻塞进程B。这时从处理器上执行的角度看,线程2实际上并不处于运行态,但是在线程库看来它处于运行态。

c)时钟中断把控制传给内核,内核改变进程B的状态。

d)线程2运行到进程B的线程1执行某些动作的一个点。此时线程2阻塞,线程1由就绪转换为运行。

 

       用户级线程相对与内核级线程的优点:

1)      由于所有线程管理数据结构都在一个进程的用户地址空间中,线程切换不需要内核态特权,因此,进程不需要为了线程管理而切换到内核态,这节省了两次状态转换的开销。也就是说在用户级线程中,线程切换对内核而言是透明的

2)      调度可以是应用程序相关的。应为不同应用程序适合不同的调度算法(轮转调度,基于优先级调度等)。所以可以为应用程序量身定做调度算法而不扰乱底层的操作系统调度程序。

3)      用户级线程可以在任何操作系统中运行,不需要对底层内核进行修改以支持用户级线程。线程库是一组供所有应用程序共享的应用程序级别的函数。

       用户级线程相对于内核级线程也有两个明显的缺点:

1)      在典型的操作系统中,许多系统调用都会引起阻塞。因此,当用户级线程执行一个系统调用时,不仅这个线程会被阻塞,进程中的所有线程都会被阻塞。这就是上图的b

2)      在纯粹的用户级线程策略中,一个多线程应用程序不能利用多处理技术。内核一次只把一个进程分配给一个处理器,因此一个进程中只有一个线程可以执行。

 

3.2 jacketing(外套,马甲)技术

       为了解决用户级线程的缺点,使用一种称作jacketing的技术。jacketing的目标是把一个产生阻塞的系统调用转化成一个非阻塞的系统调用。例如,不是直接调用一个系统I/O例程,而是让线程调用一个应用级的I/O jacket例程,这个jacket例程中的代码用来检查并确定I/O设备是否忙。如果忙,该线程进入阻塞状态并将控制传送给另一个线程。当这个线程后来又重新获得控制时,jacketing例程会再次检查I/O设备。

 

3.3内核级线程

       在一个纯粹的内核级线程软件中,有关线程管理的所有工作都是有内核完成的,应用程序部分没有进行线程管理的代码,只有一个到内核设施的应用程序接口(API)。如图4.6b

       调度是由内核基于线程完成的,该方法克服了用户级线程的两个缺点。但是内核级线程的主要缺点就是:在把控制从一个线程传送到同一个进程内的另一个线程时,需要到内核状态的切换。

       一般的情况,从表面上开,内核级线程比纯进程有性能提升,用户级线程进一步提升性能。但是这个额外的提高能否实现取决于应用程序的性质。

 

3.4组合方法

       如图4.6c。在组合的系统中,线程创建完全在用户空间,线程的调度和同步也在应用程序中进行。多个用户线程被映射到一些内核线程上。程序员可以为特定的应用程序和处理器调节内核级线程的数目,以达到整体最佳效果。

       在组合方法中同一个进程的不同线程可以在多个处理器上并行地运行,某个会引起阻塞的系统调用不会阻塞整个进程。如果设计正确,该方法将会结合用户级/内核级线程的优点而减少它们的缺点。

 

4对称多处理器

       对称多处理器(SMP)主要是些设计方面的问题,了解下面的并行处理器体系结构就可以了。

5习题

1)请列出线程间的状态切换比进程间状态切换开销更低的原因?

    如果是用户级线程的话,首先线程切换比进程切换少了两次模式切换。

    另外进程切换比线程切换开销大是因为进程切换时要切页表,而且往往伴随着页调度,因为进程的数据段代码段要换出去,以便把将要执行的进程的内容换进来。本来进程的内容就是线程的超集。而且线程只需要保存线程的上下文(相关寄存器状态和栈的信息)就好了,动作很小。

2)在进程概念中体现的两个独立且无关的特点是什么?

  资源所有权、调度/执行——可以从这两个方面对进程/线程进行思考。

3)给出在单用户多处理系统中使用线程的四个例子。

     前台和后台操作,异步处理,加速执行和模块化程序结构。

4)哪些资源通常被一个进程中的所有线程共享?

      例如地址空间,文件资源,执行特权等。