线程模型

来源:互联网 发布:电信光纤网络优化大师 编辑:程序博客网 时间:2024/06/09 16:52

当今的各种不同的操作系统都各自实现了自己的线程调度模型,这些不同的调度模型之间的不同是:在竞争系统资源的时候,特别是竞争CPU资源的时候,各个线程所处的竞争范围不同;有以下两个不同的竞争范围:
线程竞争范围:
A、进程竞争范围:各个不同的线程在同一个进程中竞争"被调度的CPU时间"(但是不直接和其它进程中的线程竞争);
B、系统竞争范围:线程直接和"系统范围"内的其它线程竞争,无论它们与什么进程关联;

当今的操作系统所实现的线程基本上有三种线程调度模型:
(1)、N:1的用户线程模型:
早期的"线程实现"是建立在原始的OS"进程控制"机制之上的,并由用户空间中的程序库来管理.因此,操作系统并不知道线程的信息."调度进程和程序库"的内核在同一个进程中管理N个线程.因此,这种线程模型被称为是"N:1"的用户线程模型,这些线程也被称为是用户空间线程或用户线程;在N:1的用户线程模型中,所有的线程都工作在"进程竞争范围";比如:HP-UX10.20和SunOS4.x这两个平台就提供了N:1用户线程模型;
在N:1的用户线程模型中,内核并不干涉线程的任何生命活动,也不干涉同一个进程中的环境切换.因此,线程的创建、删除和环境切换都很高效;但是这个模型有两个问题:
A:无论主机有多少个CPU,一个进程只会被调度到一个CPU上.这个进程中的所有线程都会竞争那一个CPU,内核进行进程调度时所分配的任何CPU时间片都被这个进程中的所有线程所共享;
B:如果某一个线程执行了一个"阻塞式"操作,那么,这个进程中的所有线程都会被阻塞,直到那个阻塞式操作结束;
N:1模型图如下:

线程模型 - 哥哥 - 哥哥
(2)、1:1的内核线程模型:
现代OS内核大多都提供了对线程的直接支持;在"1:1"内核线程模型中,应用程序创建的每一个用户线程都由一个内核线程直接管理.OS内核把每一个内核线程都调度到系统CPU上;这样的话,应用程序创建的每一个用户线程都有机会获得系统CPU的时间片而不会被其它线程的阻塞式操作所阻塞;因此,在"1:1"内核线程模型中,所有的线程都工作在"系统竞争范围".HP-UX11、Linux和Windows NT/2000平台都提供了1:1内核线程模型;
N:1用户线程模型中的两个问题在1:1内核线程模型中得到解决:
A:如果有多个CPU可用,则多线程应用程序可以利用这些CPU;
B:如果内核在系统函数中阻塞了一个线程,则其它线程仍然能继续运行,而不会受到影响;
 但是,OS内核涉及线程的创建和调度,所以,较之N:1模型,在使用1:1模型时,线程的生命周期操作更昂贵;
1:1模型图如下:
线程模型 - 哥哥 - 哥哥
(3)、N:M的混合线程模型:
有一些操作系统,比如Solaris,它提供了N:1模型和1:1模型的混合模型,即"N:M"混合线程模型.这个模型支持用户线程模型和内核线程模型的混合形式;当应用程序创建线程的时候,它可以指明这个线程应该工作在哪一个竞争范围(在Solaris中,默认选择的是"进程竞争范围").OS线程库创建一个用户空间(user-scope)线程,但是只在需要的时候,或者是在应用程序有明确请求"系统竞争空间"的时候,它才会创建一个内核线程;就像在1:1模型中的那样,OS内核把内核线程调度到CPU上,但是也像在N:1模型中的那样,OS线程库把"用户空间线程"调度到一个"轻量级进程(LWP)"上,然后每一个LWP都映射到一个内核线程上;
但是N:M模型也有自己的问题;多个"用户空间线程"中,只要有一个线程调用了阻塞式系统函数,其它线程就会都被阻塞.如果OS内核阻塞了一个LWP,则被线程库调度到这个LWP上的所有用户线程也都会被阻塞,但是被调度到其它LWP上的用户线程仍然能继续运行,而不受影响;Solaris系统通过二分法来解决这个问题;这种二分法基于"调度者激活"的规则:
A:OS线程库维护着一个LWP池,用来运行所有"进程范围"内的用户线程.在需要的时候,它可以把这些用户线程重新调度到池中的LWP上.池的大小可以通过pthread库中的pthread_setconcurrency()函数来调整;也就是调整线程的并发度;
B:如果OS内核发现进程中所有内核线程都被阻塞了,则会向受影响的进程发送SIGWAITING信号;线程库捕获到这个信号之后,会启动一个新的LWP,然后它把一个"进程范围"内的线程重新调度到这个新启动的LWP上,使得应用程序可以继续运行;
N:M模型图如下:

线程模型 - 哥哥 - 哥哥

0 0