Windows进程与线程学习笔记(四)—— 等待链表&调度链表

前言

一、学习自滴水编程达人中级班课程,官网:https://bcdaren.com
二、海东老师牛逼!

要点回顾

  1. 进程结构体 _EPROCESS +0x050_EPROCESS +0x190 这2个链表圈着当前进程所有的线程
  2. 对进程断链,程序可以正常运行,原因是CPU执行与调度是基于线程的,进程断链只是影响一些遍历系统进程的API,并不会影响程序执行
  3. 对线程断链也是一样的,断链后在Windbg或者OD中无法看到被断掉的线程,但并不影响其执行(线程仍然在跑)

33个链表

  1. 线程有3种状态:就绪等待运行
  2. 正在运行中的线程存储在KPCR中,就绪等待的线程全在另外的33个链表中:
    1个等待链表,32个就绪链表
  3. 等待链表调度链表都使用了 _KTHREAD +0x060 这个位置,也就是说,线程在某一时刻,只能属于其中一个圈

等待链表

描述

  1. 等待链表是一个双向链表
  2. 它有两个成员,一个向后遍历,一个向前遍历
  3. 当线程调用了Sleep() 或者 WaitForSingleObject()等函数时,就挂到这个链表(查看等待线程)

在WinDbg中查看

kd>dd KiWaitListHead

KiWaitListHead

kd>dt _KTHREAD

KTHREAD

实验:分析等待链表中的线程所属的进程

第一步:查看所属线程结构体:

EHTREAD

第二步:查看所属进程结构体

EPROCESS

调度链表

描述

  1. 调度链表共有32个双向链表
  2. 线程在调度链表的中下标表示线程级别(0~31)
  3. XP中,调度链表共有32个圈;在64位操作系统(如win7 64位)中,调度链表共有64个圈
  4. 单核CPU操作系统中,无论是XP还是win7,都只有一组调度链表
  5. 但是在服务器版本系统中:等待链表只有一个,调度链表的数量等于CPU的数量

在WinDbg中查看

dd KiDispatcherReadyListHead L70

KiDispatcherReadyListHead

总结

  1. 线程总数 = 1个等待链表 + 调度链表数量*CPU数量 + 1个正在运行的线程
  2. 无论是等待链表还是调度链表,在线程结构体中都位于 _KTHREAD +0x060 这个位置
发布了45 篇原创文章 · 获赞 2 · 访问量 1840

猜你喜欢

转载自blog.csdn.net/qq_41988448/article/details/103055173