进程、线程调度模型及其在Windows2000中的实现

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

与内核级线程相对应的,是用户级线程。这类实现多见于一些历史悠久的操作系统(如Unix系列),为了在操作系统中加入线程支持,采用了在用户空间增加运行库来实现线程。这些运行库被称为“线程包”。
进程、线程调度模型及其在Windows2000中的实现
在传统的操作系统中,每个进程有一个自己的地址空间以及一个单一的控制流程。事实上,这几乎就是传统操作系统中进程的定义。
但是,现实中有很多情况下需要在同一个地址空间中完成并行的任务,比如Web服务器程序,虽然使用多进程方式编程也可以很好地实现服务器,但进程间的数据共享由于需要跨越地址空间而显得十分不方便,同时进程间切换的开销也不可小视。
其实,在用户等待磁盘操作完成的时候,虽然进程对用户的输入无响应,但CPU确实是空闲的(假定没有忙碌的后台进程),理论上CPU应该可以响应用户输入。这样,我们就回到了多任务系统的设计初衷:提高CPU利用率。
我们先来讨论两个不使用线程模型的解决方案:多进程编程和使用异步系统调用。
如果使用多进程方式,则由主进程新建一个工作进程,将需要保存的数据传递给工作进程以进行保存操作。如果需要保存的数据量非常大,内存间的数据复制是一个可观的开销。当然,在较新的操作系统如System V中,由于采用COW(Copy On Write)技术,这个性能损失可以略过。另一个改进办法是使用共享内存,在一些不使用fork方式新建进程的操作系统上这是个好办法。
这两条路那一条都不是很方便。问题的关键在于,同步对象的句柄值只是每个进程对象表中的索引,在另一个进程中是无效的。但在线程模型下,这个问题就迎刃而解了。因为(同一进程中的)线程间共享同一张内核对象表,所以同一个同步对象的句柄对各线程来说都是有效的,传递时只要直接传句柄值就行了。
另一个比较实际的例子是字处理软件。假设现在正在编辑一篇重要文章,为了减少由于断电而造成的损失,软件被设定为每隔1分钟自动存盘一次。
如果在传统操作系统下,由于一个进程只有一个执行流,每当2分钟的间隔到达后,进程转向响应定时器软中断(在Unix下为进程收到信号,并执行信号处理过程),这样所有的处理用户输入的代码被挂起,直至磁盘读写完成,信号处理程序返回为止。如果很不幸地,文章非常长,或者用户在软盘或网络驱动器上工作,每次保存文章所花时间为50秒(如果是61秒用户就幸运了,但没人想要这样的幸运),那么用户几乎没有时间去编辑文章,这样的软件特性显然毫无用处。
若使用线程模型,则没有上述两个问题。字处理进程可以采用两个线程,前后界面线程和后台工作线程。界面线程负责响应用户输入,工作线程平进处于挂起状态,并且由主线程定时把它唤醒进行数据保存工作。这样,用户可以在几乎无察觉的情况下定时保存文档。
线程的实现
由上文的定义,线程为进程中的一个或多个指令执行流,这个机制在现代操作系统的实现主要可分为两大类。即根据操作系统内核是否对线程可感知,分为内核环境下进行多道程序设计成为可能。由于同一个进程所属的线程间共享同一地址空间,所以线程间可以能过直接传递指针来传递数据,而这在传统的进程模型下是不可能实现的。不单如此,线程间还可以共享内核对象,使得许多任务得以简化。
比如,同步对象的使用。在传统操作系统中,要将一个同步对象的句柄传递给另一个进程,有两条路可以走:通过父子进程间的继承关系(如Unix中的fork系统调用)或是通过对象命名,然后再在另一个进程中以同样的名字打开。
而所谓指令流程,实际上指的是操作系统调度占用CPU的实体,我们称之为“线程”(thread of execution)。
每个线程拥有自己的用户栈、核心栈、程序计数器等,线程与传统的进程类似,也有运行、挂起、就绪等状态,在状态间的转换也类似。但与传统进程所不同的是,线程没有独立的地址空间,所有属于同一个进程的线程共享同一个线性地址空间。
若使用异步系统调用,则需要编写一系列信号处理程序。主程序在运行时跟踪并记录当前状态,在信号出现时转到信号处理程序,处理完成后根据处理前的状态继续运行。这种方案采用的是有限状态自动机的思想,可以避免多进程操作时的同步及数据传递问题,但它使得程序变得相当复杂。
这两种办法都是可行的,但前者通讯开销比较大,后者如果运行在多CPU主机上,则无法充分利用CPU资源。
其实这些问题的本质在于两个概念:
1. 资源的分组
2. 指令的执行流程
所谓资源分组,是指操作系统以什么为最小单位给用户程序分配资源以及对这些资源进跟踪。这里提到的资源,指的是打开文件、同步对象、管道等,以及进程最重要的标志:地址空间。
在现代操作系统中,进程就是所谓的资源分配的最小单位。一个进程拥有自己独立的地址空间、内核对象表(记录打开文件、同步对象等等)、进程句柄等。
由此可知,在线程模型下,操作系统进行资源分配是以进程为单位,而当操作系统进行任务调度时,则以线程为单位进行。当然这并不是说进程和线程间没有直接关系。恰恰相反,进程与线程间的关系非常密切。线程要占用CPU执行预定任务,没有资源是不可能的完成任务的;同时,只有资源而没有指令流的进程也是没有意义的。所以结果是,一个进程至少包含一个线程(称为主线程或初始线程),而一个线程只属于一个进程。
实际上,上文所说的线程是操作系统调度的基本单位,实际上指的只是内核线程。所谓内核线程,其建立与销毁都是由操作系统负责、通过系统调用完成的。操作系统在调度时,参考各进程内的线程运行情况做出调度决定,如果一个进程中没有就绪态的线程,那么这个进程也不会被调度占用CPU。
事实上在Windows 2000中,操作系统进行调度时根本就不理采线程是属于哪个进程的,只是将所有的就绪线程统一排成若干个优先级队列,然后进行调度。在这个情况下,线程的确成了调度的最小单位,所以有时线程也被称为“轻量级进程”。
相关文档
最新文档