多线程:线程模型-小结

一.基础知识:线程和进程

按照教科书上的定义,进程是资源管理的最小单位,线程是程序执行的最小单位。在操作系统设计上,从进程演化出线程,最主要的目的就是更好的支持SMP以及减小(进程/线程)上下文切换开销。

 

无论按照怎样的分法,一个进程至少需要一个线程作为它的指令执行体,进程管理着资源(比如cpu、内存、文件等等),而将线程分配到某个cpu上执行。一个进程当然可以拥有多个线程,此时,如果进程运行在SMP机器上,它就可以同时使用多个cpu来执行各个线程,达到最大程度的并行,以提高效率同时,即使是在单cpu的机器上,采用多线程模型来设计程序,正如当年采用多进程模型代替单进程模型一样,使设计更简洁、功能更完备,程序的执行效率也更高,例如采用多个线程响应多个输入,而此时多线程模型所实现的功能实际上也可以用多进程模型来实现,而与后者相比,线程的上下文切换开销就比进程要小多了,从语义上来说,同时响应多个输入这样的功能,实际上就是共享了除cpu以外的所有资源的。

 

保留意见:对于单cpu而言,多线程无疑是自绑双脚。多余多CPU而言,才有意义。

 

针对线程模型的两大意义,分别开发出了核心级线程和用户级线程两种线程模型分类的标准主要是线程的调度者在核内还是在核外

 

线程的调度者在核内

更利于并发使用多处理器的资源

线程的调度者在核外

则更多考虑的是上下文切换开销。

 

 

在目前的商用系统中,通常都将两者结合起来使用,既提供核心线程以满足smp系统的需要,也支持用线程库的方式在用户态实现另一套线程机制,此时一个核心线程同时成为多个用户态线程的调度者。正如很多技术一样,"混合"通常都能带来更高的效率,但同时也带来更大的实现难度,出于"简单"的设计思路Linux从一开始就没有实现混合模型的计划,但它在实现上采用了另一种思路的"混合"

 

在线程机制的具体实现上,可以在操作系统内核上实现线程,也可以在核外实现,后者显然要求核内至少实现了进程,而前者则一般要求在核内同时也支持进程。核心级线程模型显然要求前者的支持,而用户级线程模型则不一定基于后者实现。这种差异,正如前所述,是两种分类方式的标准不同带来的。

1)核内 "多对多"模型

 

当核内既支持进程也支持线程时,就可以实现线程-进程的"多对多"模型,即一个进程的某个线程由核内调度,而同时它也可以作为用户级线程池的调度者,选择合适的用户级线程在其空间中运行。这就是前面提到的"混合"线程模型,既可满足多处理机系统的需要,也可以最大限度的减小调度开销。绝大多数商业操作系统(如DigitalUnix、Solaris、Irix)都采用的这种能够完全实现POSIX1003.1c标准的线程模型。

 

2)核外 模型分为:"一对一"、"多对一"两种模型

--2.1)核外 一对一模型:

 

在核外实现的线程模型,用一个核心进程(也许是轻量进程)对应一个线程,将线程调度等同于进程调度,交给核心完成

--2.2)核外多对一模型:

完全在核外实现多线程,调度也在用户态完成核外多对一模型‘就是前面提到的单纯的用户级线程模型的实现方式,显然,这种核外的线程调度器实际上只需要完成线程运行栈的切换,调度开销非常小,但同时因为核心信号(无论是同步的还是异步的)都是以进程(task_struct为调度数据结构)为单位的,因而无法定位到线程,所以这种实现方式不能用于多处理器系统,而这个需求正变得越来越大,因此,在现实中,纯用户级线程的实现,除算法研究目的以外,几乎已经消失了。

 

linux内核的“线程模型”实现方案:是核外 一对一模型

Linux内核只提供了轻量进程的支持,限制了更高效的线程模型的实现,但Linux着重优化了进程的调度开销,一定程度上也弥补了这一缺陷。目前最流行的线程机制LinuxThreads所采用的就是"线程-进程"一对一"模型",调度交给核心,而在用户级实现一个包括信号处理在内的线程管理机制。Linux-LinuxThreads的运行机制正是本文的描述重点。

 

线程模型的实现:LinuxThreads  2.6.以前使用NPTL2.6之后内核使用内核+GLIBCandroidbionic)。

LinuxThreads是目前Linux平台上使用最为广泛的线程库,由Xavier Leroy (Xavier.Leroy@inria.fr)负责开发完成并已绑定在GLIBC中发行它所实现的就是基于核心轻量级进程 "一对一"线程模型,一个线程实体对应一个核心轻量级进程,线程之间的管理在核外函数库中实现理解:创建一个用户线程的时候,"调度"靠“轻量级进程”,管理线程资源靠“核外函数库”。


二  线程发展历史-linux

线程的实现机制

线程的实现,经历了如下发展阶段:

  • 实现机制

    模型

    实现库封装

    应用情况

    LinuxThreads :

    1:1

    glibc

     Linux2.6之前使用

    NPTL (Native Posix Thread Library) :

    1:1

    glibc

    实现在glibc\nptl

     

     RedHat负责,Linux2.6之使用

    NGPT (Next Generation Posix Thread):

    M:N

    未知

    IBM负责,同NPTL同时开始研究的,但是最后被抛弃了(IBM啊...哎...)



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值