线程等待与唤醒之win32内核浅析

线程唤醒与等待

等待对象

  • 伪代码 解释 基于win32 等待对象 与 当前线程 ,被等待对象的关系.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

//被等待对象1
int Thread
{
int a = 0;
return a++;
}

//被等待对象2
int Thread1
{
int a = 0;
return a++;
}

//当前主线程
void main(...)
{
//被等待对象
int a Thead.t1.start;
int a1 = Thead1.t1.start;

解析 -> 等待对象
waitingforSinglObject(arr[t1,t2],xx);

只有等待: 等待对象中的被等待对象t1和t2执行完后,当前main线程才能继续执行.
printf(...);
}

逻辑步骤-TODO

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
WaitForSingleObject调用内核函数NtWaitForObject,

NtWaitForObject 调用ObReferenceObjectByHandle,通过当前线程对象句柄找到'等待对象结构体'的首地址

将结构体首地址传递给 KeWaitSingleObject


KeWaitSingleObject 步骤:

1,准备等待块._wait_block; 默认初始4个等待块
..... 这块内核比较复杂黑盒,todo


被等待对象:必须具备_DISPATCHER_HEADER属性的对象,

_DISPATCHER_HEADER结构体
{
...
...
+0x004 SingleStat; 信号状态 > 0;
+0x008 WaitListHead; 所有等待块双向链表地址.

}

内部处理逻辑伪代码:

while(1)
{
if(符合条件) // 1,符合超时条件, 等待对象的信号量 > 0;
{
1,修改等待对象的singleStat;
2,退出循环
}
else
{
if(不符合条件) // 超时并且被等待对象 !>0;
{
if(第一次执行)
{

}

}

}
// 将waitingblockList 位置清0;
//释放_kwait_block等待块内存.
}