线程模型,内核线程,用户线程

来源:互联网 发布:淘宝和访客交流 编辑:程序博客网 时间:2024/06/06 18:19

内核调度的是内核线程,每个内核线程是内核的一个分身,是内核的一个调度单元。用户线程基于内核线程,根据内核线程对用户线程的支持情况分为三种模式:一对一,多对一,多对多(注意,这三种模式都是针对于一个进程来讲的)。一对一:为一个进程的每一个用户线程都分配一个内核线程,当其中一个线阻塞时,其他线程不受影响。受到的限制是内核支持的总的内核数目有限。多对一:为一个进程的所有用户线程只分配一个内核线程,当该线程阻塞时整个进程阻塞。多对多:为一个进程的所有用户线程分配若干内核线程,前两种模式的折中。

直接看下面的网页,有图,精彩!

http://wenku.baidu.com/view/956c93d6195f312b3169a574.html  

进程:

用户线程:一般的用户线程

轻量级进程(LWP):基于内核线程的用户线程

内核线程:支持LWP的内核里的线程

http://hi.baidu.com/xtianhe/blog/item/b6d31dfe719ed68f59ee909b.html

http://www.cnitblog.com/tarius.wu/articles/2277.html  原创者?

在现代操作系统中,进程支持多线程。进程是资源管理的最小单元;而线程是程序执行的最小单元。一个进程的组成实体可以分为两大部分:线程集合资源集。进程中的线程是动态的对象;代表了进程指令的执行。资源,包括地址空间、打开的文件、用户信息等等,由进程内的线程共享。

线程有自己的私有数据:程序计数器,栈空间以及寄存器。

Why Thread?(传统单线程进程的缺点)

<!--[if !supportLists]-->1. <!--[endif]-->现实中有很多需要并发处理的任务,如数据库的服务器端、网络服务器、大容量计算等。

<!--[if !supportLists]-->2. <!--[endif]-->传统的UNIX进程是单线程的,单线程意味着程序必须是顺序执行,不能并发;既在一个时刻只能运行在一个处理器上,因此不能充分利用多处理器框架的计算机。

<!--[if !supportLists]-->3. <!--[endif]-->如果采用多进程的方法,则有如下问题:
a. fork
一个子进程的消耗是很大的,fork是一个昂贵的系统调用,即使使用现代的写时复制(copy-on-write)技术。
b.
各个进程拥有自己独立的地址空间,进程间的协作需要复杂的IPC技术,如消息传递和共享内存等。

多线程的优缺点

多线程的优点和缺点实际上是对立统一的。

支持多线程的程序(进程)可以取得真正的并行(parallelism),且由于共享进程的代码和全局数据,故线程间的通信是方便的。它的缺点也是由于线程共享进程的地址空间,因此可能会导致竞争,因此对某一块有多个线程要访问的数据需要一些同步技术。

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

内核线程

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

轻量级进程[*]

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

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

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

LWP.JPG

注:

<!--[if !supportLists]-->1.   <!--[endif]-->LWP的术语是借自于SVR4/MPSolaris 2.x

<!--[if !supportLists]-->2.   <!--[endif]-->有些系统将LWP称为虚拟处理器。

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

 

用户线程

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

Uthread1.JPG

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

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

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

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

小结:

很多文献中都认为轻量级进程就是线程,实际上这种说法并不完全正确,从前面的分析中可以看到,只有在用户线程完全由轻量级进程构成时,才可以说轻量级进程就是线程。

 

http://www-900.ibm.com/cn/support/faqhtmlfaq/2011993000004.htm

线程调度策略分析


线程调度策略模型介绍及分析

线程调度策略
在AIX中,取决于用户线程映射到核心线程的方式,可以有三种不同的调度方式
- 1:1 方式
- M:1 方式
- M:N 方式
核心线程既轻量级线程。用户线程映射到核心线程的处理是通过虚拟处理器(VP)完成的,换句话说,用户线程的调度首先映射到VP, 由VP调度,VP是一个核心线程,或者是绑定到核心线程的结构。下面将给出这三种方式的详细介绍。
1) 1:1调度方式
在这种方式中,每一个用户线程绑定到一个VP上,即一个核心线程,而VP并不一定绑定到
物理的CPU,除非是执行绑定到CPU的操作。从用户级看,每一个VP是一颗可以运行用户
代码或者系统调用的CPU。绑定到VP的线程,将直接被核心调度器调度,具有系统级的范围。
可以用图示的方式直观的标示如下:
image
2) M:1调度方式
在M:1调度方式下,所有的用户线程映射到一个VP即一个核心线程。这种映射方式是有POSIX线程库调度器完成的,所有的用户线程编程工具完全有POSIX线程库管理。这种调度方式可适用于任何UNIX系统,特别是在一些传统的单线程系统中,使用更广泛,图示如下:
image
3) M:N调度方式
在M:N的调度方式下,几个用户线程可共享同一个VP,或者同一个VP共享池。一个未绑定VP的用户线程,可以称为本地或进程范围的线程,这样的线程不能用核心调度器直接调度,POSIX线程库调度器将处理用户线程到VP的映射,然后核心调度器将直接调度与之相关的核心线程。在三种调度方式中,这是最复杂、最有效的一种调度策略。
用户及线程编程工具被POSIX线程和核心线程共享。图示如下:
image
进程调度是UNIX的核心组成部分,按照一定的调度策略,调度处于运行状态的进程。从AIX4.3版本开始,AIX在进程级别支持线程的调度,用户线程调度器由POSIX线程库提供,支持M:N调度模式。对应于用户线程,POSIX线程库调度器有一个或一组VP对应,这种对应方式,为进程创建多个线程,充分利用核心资源提供了支持。
POSIX线程库通过编程控制线程的调度,有两种不同的实现方法:
1) 常见线程时设置调度属性值
2) 动态的改变调度属性值
另外,AIX操作系统也为用户改变线程的调度提供了相应的环境变量。
AIX系统支持三种不同POSIX线程调度策略:
1) SCHED_FIFO,先进先出的调度策略。每一线程都有一固定的优先级,当多个线程
具有同一优先级时,各线程按照先进先出的策略调度运行,直至结束。
2) SCHED_RR,Round_robin(RR)调度方式,每一线程具有固定的优先级,当多个线程具有同一优先级时,按照先进先出的调度策略,运行固定的时间片。
3) SCHED_OTHER,这是AIX缺省的调度策略,每一线程都有一初始的优先级,但是随着
线程的运行而动态的改变优先级。
通常情况下,应用程序应使用缺省的调度策略,对一些特殊的应用程序,要求使用固定
的优先级时,可以考虑使用SCHED_RR或SCHED_FIFO的调度策略。使用RR策略是应确定
所有的线程都有固定的优先级,这种调度策略对使用线程读取传感器或写控制器时特别有效。
在使用FIFO调度策略时应注意,因为线程除非被某些调用阻塞,否则将一直运行至结束,
所以对高优先级的线程会造成负面的影响。
AIX操作系统也提供一些环境变量影响线程的调度策略,这里只介绍两个环境变量AIXTHREAD_SCOPE和AIXTHREAD_MNRATIO。
AIXTHREAD_SCOPE:如果线程使用缺省的线程属性值创建,这个值可以设定线程的范围,
使用方法为:
AIXTHREAD_SCOPE=[P|S]
P标示进程范围,S标示系统范围,如果没有设定此环境变量,则作用于进程范围,执行M:N的调度方式,如制定此值为S,则使用1:1的调度方式。
AIXTHREAD_MNRATIO:这个环境变量,将指定用户线程与核心线程之间的映射比例,设定
方法为:
AIXTHREAD_MNRATION=p:k
k是对应于用户线程p的核心线程数,对于p,k值由以下几种处理:
1) 如AIXTHREAD_SCOPE值为S,则为用户线程与核心线程的比率为1:1
2) 如AIXTHREAD_SCOPE值为P,则缺省比率为8:1,否则为设定值
3) 如k值大于p值,则认为是1:1的对应比率