zoukankan      html  css  js  c++  java
  • 线程被动切换(时间碎片)

    Windows内核分析索引目录:https://www.cnblogs.com/onetrainee/p/11675224.html

    线程被动切换(时间碎片) - KiReadyThread函数详细分析

    每个线程都存在自己的时间碎片(_KTHREAD+0x6f QuanTum),当时间到了之后,其会让其他线程运行,现在我们就来详细分析一下其有关细节。

     

    时间片更新函数:

    HalpHpetClockInterrupt->KeUpdateSystemTime->KeUpdateRunTime

    时间片检查函数:

    HalEndSystemInterrupt->KiDispatchInterrupt

     

    时间更新是利用CPU的DPC机制,所谓DPC就是类似于看门狗,CPU运行一定时间就会调用DPC运行某个DPC函数,之后我们再来详细分析DPC这块的内容。

     

    1)_KiDispatchInterrupt 函数分析

      时钟中断最后会调用 _KiDispatchInterrupt 这个函数,该函数思路比较清晰,判断时间碎片等有关函数。

      其中关键的说Windows是采用抢占模式的其实就看一行代码:

      “②”中如果其不存在下一个线程 KPCR.NextThread,其并不会去主动去找,而是继续运行原来线程,所以是主动抢占式的;其不存在一个队列,每个线程有序运行。

      操作系统就看一个KPCR.NextThread,如果该值为空就继续运行原来的线程。

      

    2)_KiReadyThread 函数分析

      该函数是对于原来老的线程的处理,通过分析它你可以清楚地理解线程切换更详细的过程,但同时其也做了很多额外工作,比如线程的进程不在内存中,其会映射进内存。

      我们应该分析其主干,对于涉及的额外的工作,我们并不要花过多精力去分析,这一点我们首先是要明确的。

      (1)其先找到合适的CPU,在我们单核情况下其就存在单独一个CPU;

      (2)判断CPU的 KPRCB.NextThread是否为空:

        当为空时:

          ① 判断当前线程优先级和老的线程优先级的大小;

          ② 如果老的线程优先级比较大,则直接放入KPCR.NextThread中;否则放入线程的等待队列中 - KThread.WaitListEntry中

          ③ 其中老线程是被抢占的(preemted),则放入 KThread.WaitListEntry头部,作为补偿,否则放入尾部。

        当不为空时:

          ① 比较NextThread和老线程的优先级大小;

          ② 如果老的线程比较大,则放入KPCR.NextThread,而原来的老线程会设置有关标志位再去找自己合适的位置。

          ③ 否则放入线程的等待队列中 - KThread.WaitListEntry中其中老线程是被抢占的(preemted),则放入 KThread.WaitListEntry头部,作为补偿,否则放入尾部。

      注释:在分析中会涉及到大量的进程与线程状态转换,我们从WRK中找到下列的有关定义,结合这个能帮助我们的理解。

      

    3)_KiReadyThread 函数分析逆向细节

      这函数分支比较庞大,我们在这里就按照上面所说的,简要的画出其步骤流程图,很多地方已经加了注释,比较好理解的。

  • 相关阅读:
    docker node中uid与gid的授权问题
    windows下docker无法进行端口映射的问题
    IOS/Safari下document对象的scrollHeight值比Chrome更大
    Vue/Egg大型项目开发(二)数据库设计
    .babelrc和babel.config.js的相同配置不能合并
    es6 class中责任链模式与AOP结合
    JS设计模式(10)职责链模式(重要)
    Vue/Egg大型项目开发(一)搭建项目
    你不知道的JS(3)来聊聊this
    CentOS7为php7.2安装php-redis扩展(redis环境搭建二)
  • 原文地址:https://www.cnblogs.com/onetrainee/p/12755998.html
Copyright © 2011-2022 走看看