• (转)Windows的线程管理和调度机制


    线程,有时被称为轻量级进程,是程序执行流的最小单元。一个标准的线程由线程ID,当前指令指针,寄存器集合和堆栈组成。另外,线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。

    既然线程作为程序执行流的最小单元,那么在Windows中,是怎样管理和调度线程的呢?在Windows NT以后,Windows实现了一个基于优先级的抢先式多处理器调度系统。调度系统总是运行优先级最高的就绪线程。通常线程可在任何可用处理器上运行,但也可限制某线程只能在某处理器上运行。

    先看一下优先级是怎么划分的。线程总共分为32个优先级,具体看下图:


    线程优先级分为实时(从16到31,如设备监控线程)和可变优先级(从1到15),级别0保留为系统使用。线程的基本优先级=[进程的基本优先级 - 2,进程的基本优先级 + 2] ,由应用程序控制。线程的动态优先级 = [ 进程的基本优先级 - 2, 31] ,由NT 核心控制。为了提高调度速度,Windows NT维护了一个称为就绪位图的32位量。就绪位图中的每一位指示一个调度优先级的就绪队列中是否有线程等待运行。还有一个称为空闲位图的32位量用来指示一个处理机是否处于空闲状态。

    但光有线程的优先级的话那么相同优先级的线程中只有一个执行到底,其他的都处于等待,所以还有一个时间配额的制度。时间配额是一个线程从进入运行状态到系统检查是否有其他优先级相同的线程需要开始运行之间的时间总和。一个线程用完了自己的时间配额时,如果没有其它相同优先级线程,Windows 2000将重新给该线程分配一个新的时间配额,并继续运行。每个线程都有一个代表本次运行最大时间长度的时间配额。

    在每个线程拥有优先级和时间配额后,通常线程先在许多等待函数的调用中进入等待状态,进入等待状态线程的时间配额不会被重置,而是在等待事件出现时,线程的时间配额被减1相当于1/3个时钟间隔;如果线程的优先级大于等于14在等待事件出现时,线程的优先级被重置。可能在这两种情况下出现抢先的情况:一个是高优先级线程的等待完成,即一个线程等待的事件出现。 一个是一个线程的优先级被增加或减少。 在判断一个线程是否被抢先时,并不考虑线程处于用户态还是内核态,调度器只是依据线程优先级进行判断。 当线程被抢先时,它被放回相应优先级的就绪队列的队首。 如果刚用完时间配额的线程优先级降低了,系统将寻找一个优先级高于刚用完时间配额线程的新设置值的就绪线程。

    如果刚用完时间配额的线程的优先级没有降低,并且有其他优先级相同的就绪线程,系统将选择相同优先级的就绪队列中的下一个线程进入运行状态,刚用完时间配额的线程被排到就绪队列的队尾(即分配一个新的时间配额并把线程状态从运行状态改为就绪状态)。 如果没有优先级相同的就绪线程可运行,刚用完时间配额的线程将得到一个新的时间配额并继续运行。 当线程完成运行时,它的状态从运行状态转到终止状态。线程完成运行的原因可能是通过调用函数而从主函数中返回或通过被其他线程通过调用函数来终止。如果处于终止状态的线程对象上没有未关闭的句柄,则该线程将被从进程的线程列表中删除,相关数据结构将被释放。

    这是Windows中大概的线程管理和调度的方法,而Windows NT中还有一个很重要的多线程的机制。

    由于线程比进程开销小而且创建得更快,同一进程内的多个线程共享同一块内存,便于线程之间数据共享和传送以及所有的进程资源对线程都有效的原因,系统采用多线程而不采用多进程来实现多任务。

    首先一个处理器在一个时刻只能执行一个线程,Windows NT允许用户同时运行多个任务。这是通过下述方法实现的:

    (1)运行一个线程,直到它被中断或进入等待状态;

    (2)保存该线程的描述表;

    (3)操作系统从等待执行的线程队列中挑选一个动态优先级最高的线程作为执行线程,装入它的描述表(一旦线程获得CPU时间片,它的动态优先级就降低,但不会低于它的基础优先级);

    (4)若还存在等待被执行的线程,则重复上述过程。

    处理器就是这样根据优先级不断地切换执行线程,它的高速度使人产生多个线程同时执行的错觉。所以一个处理器实际上仍然只能处理一个线程,这只是利用了高速度上的近似同时性。当计算机系统有多个处理器时,多线程就能实现真正的同时执行。目前,NT的对称多处理器结构(SMP)最多支持32个处理器。


    Windows NT是占先式多任务操作系统,这意味着操作系统不必等待一个线程,它可主动将处理器让给其它线程。在这种方式下,当一个线程已运行了配额的时间后,或出现抢先情况时,操作系统将中断该线程。如图所示:

    线程转让CPU处理时间是被迫的。占先式多任务可以防止线程独占CPU,允许其它线程公平地分享CPU执行时间,这和16位Windows环境下的协作式多任务有着本质的区别。在16位Windows环境下,如果一个程序进入无限循环,则其它应用程序可能永远没有机会执行;而在Windows NT环境下这种情况不会发生,相反,许多线程的执行部分都采用了循环扫描的结构。这也是实现了多线程的基础。

    以上就是Windows中大概的线程管理和调度机制。

  • 相关阅读:
    charCodeAt() 和charAt()
    去除全角空格
    string字符串js操作
    取小数的常见操作
    js取最大最小值
    js加减法运算多出很多小数点
    js设置div透明度
    setTimeout设置不起作用
    node.js 找不到 xxx 模块解决办法
    servlet 监听器和过滤器入门
  • 原文地址:https://www.cnblogs.com/wonderKK/p/2543999.html
Copyright © 2020-2023  润新知