内核支持线程 & 用户级线程

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了内核支持线程 & 用户级线程相关的知识,希望对你有一定的参考价值。

参考技术A

各种进程,包括系统进程和用户进程,它们的创建、撤销和I/O操作、切换等,都是使用系统调用进入内核,再由内核的相应处理程序完成的——可以说所有进程都是在OS内核的支持下运行。

内核支持线程(Kernel Supported Threads)就是在内核支持下运行的。使用内核支持线程的情况下,用户进程和系统进程中的线程的创建、撤销和切换都是由内核在内核空间实现。内核空间会为每一个内核支持线程设置一个TCB(线程控制块,Thread Control Block), 内核通过TCB感知一个线程的存在

内核支持线程的优点如下:

相应地,它也有一些缺点:

下面说一种在仅设置了内核支持线程的OS中可行的线程控制方法。

相比起内核支持线程是在内核空间操作的,用户级线程是存在于用户空间中。

用户级线程与内核没有什么关系,它的创建、撤销、线程间同步与通信,都无需使用系统调用。它的TCB自然也设置在用户空间,因而内核也不知道它的存在。

在仅设置了用 户级线程的系统 里, 调度以进程而不是线程为单位 ,而在仅设置 系统级线程 的系统里是 以线程为单位 的。这是它比较傻的地方,由于系统调用需要阻塞进程,当进程里的一个线程执行系统调用时,作为调度单位的整个进程都会被阻塞!而如上所说,内核支持线程中仅阻塞系统调用的线程而其他线程仍然能运行。

而在同样由于以线程为单位的原因,在多CPU系统里,内核每次只能给进程分配一个CPU,在进程里的多个线程就不能同时利用多个CPU了。

既然它有这么多缺点,自然也有许多好处来给人们采用它的理由。上面说到内核支持的用户线程切换时需要在内核态和用户态间切换,而用户级线程并不存在这个问题——所有管理用户级线程的数据结构都在用户空间中,切换也在用户空间完成,可以省一笔切换模式的开销。

另一个有点是用户级线程的实现和OS平台无关——管理线程的一切操作都在用户空间,进程还可以根据自己的需要定义自己专用的线程调度算法,这一切都不与内核的底层实现有什么关系,用户级线程甚至可以在不支持线程机制的操作系统实现!

现在我们总结一下上面讲的用户级线程的优缺点:

优点:

缺点:

用户级系统靠一个中间系统实现——运行时系统(Runtime System)。

我们来介绍一下它。运行时系统是一套管理和控制线程的函数集合,里面的各种函数有用于创建和撤销线程的、用于线程同步和通信的、切换线程、其他线程调度的等等。我们把运行时系统所有的函数都存在用户空间,作为与内核的接口——就是说用户级线程只管调用运行时系统的函数,而这些函数会自己解决怎么和内核交流和完成需要的功能。对于不同OS内核,运行时函数要采用不同的底层实现;而对于用户级线程来说调用的都是一样的函数,它与内核是无关的。

需要注意的是,系统资源最终都是由内核管理分配,用户级线程需要资源的时候也是通过调用运行时系统的函数找内核要。

既然内核支持线程和用户级线程都有自己的优缺点,把它们恰当组合起来我们可以扬长避短,得到更好的性能。

这种组合是通过内核控制线程(又称为轻型进程,Light Weight Process,LWP)实现的。

我们使系统拥有若干个内核控制线程,把它们做成一个缓冲池,称为线程池。当一个用户级线程需要内核提供的服务时,就连接到一个内核控制线程上,通过它来获得内核支持。这样一来,用户级线程也有了内核支持的属性,我们就这样把两种线程实现方式组合了起来。

每一个内核控制线程都连接在一个内核支持线程上(有可能多个内核控制线程连接在一个内核支持线程上)。用户级线程要和内核通信时必须等待没有被占用的内核控制线程,如果没有空闲的就阻塞排队。

在内核级线程执行操作时,如果发生阻塞,则与之相连接的多个内核控制线程也将随之阻塞,进而使连接到内核控制线程上的用户级线程也被阻塞。而如果在一个进程中含有多个LWP,则当一个 LWP阻塞时,进程中的其他LWP可继续执行——如果它们连接的内核支持线程没有被阻塞的话。

操作系统: 用户级线程和内核级线程

http://www.cnblogs.com/yxzfscg/p/4758728.html

三种线程——内核线程、轻量级进程、用户线程

内核线程

内核线程就是内核的分身,一个分身可以处理一件特定事情。这在处理异步事件如异步IO时特别有用。内核线程的使用是廉价的,唯一使用的资源就是内核栈和上下文切换时保存寄存器的空间。支持多线程的内核叫做多线程内核(Multi-Threads kernel )。

轻量级进程[*]

轻量级线程(LWP)是一种由内核支持的用户线程。它是基于内核线程的高级抽象,因此只有先支持内核线程,才能有LWP。每一个进程有一个或多个LWPs,每个LWP由一个内核线程支持。这种模型实际上就是恐龙书上所提到的一对一线程模型。在这种实现的操作系统中,LWP就是用户线程。

由于每个LWP都与一个特定的内核线程关联,因此每个LWP都是一个独立的线程调度单元。即使有一个LWP在系统调用中阻塞,也不会影响整个进程的执行。

轻量级进程具有局限性。首先,大多数LWP的操作,如建立、析构以及同步,都需要进行系统调用。系统调用的代价相对较高:需要在user mode和kernel mode中切换。其次,每个LWP都需要有一个内核线程支持,因此LWP要消耗内核资源(内核线程的栈空间)。因此一个系统不能支持大量的LWP。

LWP.JPG

注:

1.   LWP的术语是借自于SVR4/MP和Solaris 2.x。

2.   有些系统将LWP称为虚拟处理器。

3.   将之称为轻量级进程的原因可能是:在内核线程的支持下,LWP是独立的调度单元,就像普通的进程一样。所以LWP的最大特点还是每个LWP都有一个内核线程支持。

 

用户线程

LWP虽然本质上属于用户线程,但LWP线程库是建立在内核之上的,LWP的许多操作都要进行系统调用,因此效率不高。而这里的用户线程指的是完全建立在用户空间的线程库,用户线程的建立,同步,销毁,调度完全在用户空间完成,不需要内核的帮助。因此这种线程的操作是极其快速的且低消耗的。

Uthread1.JPG

上图是最初的一个用户线程模型,从中可以看出,进程中包含线程,用户线程在用户空间中实现,内核并没有直接对用户线程进程调度,内核的调度对象和传统进程一样,还是进程本身,内核并不知道用户线程的存在。用户线程之间的调度由在用户空间实现的线程库实现。

这种模型对应着恐龙书中提到的多对一线程模型,其缺点是一个用户线程如果阻塞在系统调用中,则整个进程都将会阻塞。

加强版的用户线程——用户线程+LWP

Uthread2.JPG

这种模型对应着恐龙书中多对多模型。用户线程库还是完全建立在用户空间中,因此用户线程的操作还是很廉价,因此可以建立任意多需要的用户线程。操作系统提供了LWP作为用户线程和内核线程之间的桥梁。LWP还是和前面提到的一样,具有内核线程支持,是内核的调度单元,并且用户线程的系统调用要通过LWP,因此进程中某个用户线程的阻塞不会影响整个进程的执行。用户线程库将建立的用户线程关联到LWP上,LWP与用户线程的数量不一定一致。当内核调度到某个LWP上时,此时与该LWP关联的用户线程就被执行。

1 .内核级线程:切换由内核控制,当线程进行切换的时候,由用户态转化为内核态。切换完毕要从内核态返回用户态;可以很好的利用smp,即利用多核cpu。windows线程就是这样的。

 2. 用户级线程内核的切换由用户态程序自己控制内核切换,不需要内核干涉,少了进出内核态的消耗,但不能很好的利用多核Cpu,目前Linux pthread大体是这么做的。

线程的实现可以分为两类:用户级线程(User-Level Thread)和内核线线程(Kernel-Level Thread),后者又称为内核支持的线程或轻量级进程。在多线程操作系统中,各个系统的实现方式并不相同,在有的系统中实现了用户级线程,有的系统中实现了内核级线程。

用户线程指不需要内核支持而在用户程序中实现的线程,其不依赖于操作系统核心,应用进程利用线程库提供创建、同步、调度和管理线程的函数来控制用户线程。不需要用户态/核心态切换,速度快,操作系统内核不知道多线程的存在,因此一个线程阻塞将使得整个进程(包括它的所有线程)阻塞。由于这里的处理器时间片分配是以进程为基本单位,所以每个线程执行的时间相对减少。

内核线程:由操作系统内核创建和撤销。内核维护进程及线程的上下文信息以及线程切换。一个内核线程由于I/O操作而阻塞,不会影响其它线程的运行。Windows NT和2000/XP支持内核线程。

用户线程运行在一个中间系统上面。目前中间系统实现的方式有两种,即运行时系统(Runtime System)和内核控制线程。“运行时系统”实质上是用于管理和控制线程的函数集合,包括创建、撤销、线程的同步和通信的函数以及调度的函数。这些函数都驻留在用户空间作为用户线程和内核之间的接口。用户线程不能使用系统调用,而是当线程需要系统资源时,将请求传送给运行时,由后者通过相应的系统调用来获取系统资源。内核控制线程:系统在分给进程几个轻型进程(LWP),LWP可以通过系统调用来获得内核提供的服务,而进程中的用户线程可通过复用来关联到LWP,从而得到内核的服务。

以下是用户级线程和内核级线程的区别:

(1)内核支持线程是OS内核可感知的,而用户级线程是OS内核不可感知的。

(2)用户级线程的创建、撤消和调度不需要OS内核的支持,是在语言(如Java)这一级处理的;而内核支持线程的创建、撤消和调度都需OS内核提供支持,而且与进程的创建、撤消和调度大体是相同的。

(3)用户级线程执行系统调用指令时将导致其所属进程被中断,而内核支持线程执行系统调用指令时,只导致该线程被中断。

(4)在只有用户级线程的系统内,CPU调度还是以进程为单位,处于运行状态的进程中的多个线程,由用户程序控制线程的轮换运行;在有内核支持线程的系统内,CPU调度则以线程为单位,由OS的线程调度程序负责线程的调度。

(5)用户级线程的程序实体是运行在用户态下的程序,而内核支持线程的程序实体则是可以运行在任何状态下的程序。

内核线程的优点:

(1)当有多个处理机时,一个进程的多个线程可以同时执行。

缺点:

(1)由内核进行调度。

用户进程的优点:

(1) 线程的调度不需要内核直接参与,控制简单。

(2) 可以在不支持线程的操作系统中实现。

(3) 创建和销毁线程、线程切换代价等线程管理的代价比内核线程少得多。

(4) 允许每个进程定制自己的调度算法,线程管理比较灵活。

(5) 线程能够利用的表空间和堆栈空间比内核级线程多。

(6) 同一进程中只能同时有一个线程在运行,如果有一个线程使用了系统调用而阻塞,那么整个进程都会被挂起。另外,页面失效也会产生同样的问题。

缺点:

(1)资源调度按照进程进行,多个处理机下,同一个进程中的线程只能在同一个处理机下分时复用

 

http://www.cnitblog.com/tarius.wu/articles/2277.html

以上是关于内核支持线程 & 用户级线程的主要内容,如果未能解决你的问题,请参考以下文章

用户线程和内核线程是否可以通过以下任何方式与线程级库和内核级库相对应?

线程的实现方式之内核支持线程和用户级线程

操作系统: 用户级线程和内核级线程

Linux第二章 Linux进程与线程(下)

用户级线程和内核级线程的区别

内核级线程(KLT)和用户级线程(ULT)