快跑与等待
1. 看似闲暇却忙碌(Busy Waiting)
2,性能监视器(Performance Monitor)
3,等待一个线程的结束
DWORD WaitForSingleObject(
HANDLE hHandle,
DWORD dwMilliseconds
);
参数
hHandle 等待对象的 handle (代表一个核心对象)。在本
例中,此为线程 handle 。
dwMilliseconds 等待的最长时间。时间终了,即使 handle 尚未成
为激发状态,此函数还是要返回。此值可以是 0
(代表立刻返回),也可以是 INFINITE 代表无
穷等待。
我如何得知一 个核心对象是否处于激发状态?
4,被激发的对象(Signaled Objects)
1) 什么是一个被 激发的对象?
1> 核心对象有两种状态:激发与未激发
2> 当核心对象被激发时,会导致 WaitForSingleObject() 醒来。稍后你将看到的 其他 Wait() 函数也是如此
例如:当线程正在执行时,线程对象处于未激发状态。当线程结束时,线程对象就被激发 了。
2) “激发” 对于不同的核 心对象有什么 不同的意义?(表格来自《win32》)
5,等待多个对象
DWORD WaitForMultipleObjects(
DWORD nCount,
CONST HANDLE *lpHandles,
BOOL bWaitAll,
DWORD dwMilliseconds
);
参数
--------------------------------------------------------------
nCount | 表示 lpH andles 所指之 handles 数组的元素个
| 数。最大容量是 MAXIMUM_WAIT_OBJECTS 。
--------------------------------------------------------------
lpHandles | 指向一个由对象 handles 所组成的数组。这些
--------------------------------------------------------------
handles | 不需要为相同的类型。
--------------------------------------------------------------
bWaitAll | 如果此为 TRUE ,表示所有的 handles 都必须激
| 发,此函数才得以返回。否则此函数将在任何一个
--------------------------------------------------------------
handle | 激发时就返回。
--------------------------------------------------------------
dwMilliseconds | 当该时间长度终了时,即使没有任何 handles 激
| 发,此函数也会返回。此值可为 0,以便测试。亦
| 可指定为 INFINITE ,表示无穷等待。
--------------------------------------------------------------
DWORD WINAPI P3_2_ThreadFunc(LPVOID n);
#define THREAD_POOL_SIZE 3
#define MAX_THREAD_INDEX THREAD_POOL_SIZE-1
#define NUM_TASKS 6
void P3_2_TaskQueSFunc()
{
HANDLE hThrds[THREAD_POOL_SIZE];
DWORD threadID;
DWORD exitCode;
int iSlot = 0;
int rc = 0;
for (int i = 0; i < NUM_TASKS; i++)
{
if (i > MAX_THREAD_INDEX)
{
rc = WaitForMultipleObjects(THREAD_POOL_SIZE,
hThrds,
FALSE,
INFINITE);
iSlot = rc - WAIT_OBJECT_0;
MTVERIFY(iSlot >= 0
&& iSlot < THREAD_POOL_SIZE);
printf("Slot %d terminated\n", iSlot);
MTVERIFY(CloseHandle(hThrds[iSlot]));
}
MTVERIFY(hThrds[iSlot++] = CreateThread(NULL,
0,
P3_2_ThreadFunc,
(LPVOID)iSlot,
0,
&threadID));
}
MTVERIFY(rc = WaitForMultipleObjects(THREAD_POOL_SIZE,
hThrds,
TRUE,
INFINITE));
MTVERIFY(rc >= WAIT_OBJECT_0
&& rc < WAIT_OBJECT_0 + THREAD_POOL_SIZE);
for (iSlot = 0; iSlot < THREAD_POOL_SIZE; iSlot++)
{
MTVERIFY(CloseHandle(hThrds[iSlot]));
}
printf("All Thread Terminated\n");
}
DWORD WINAPI P3_2_ThreadFunc(LPVOID n)
{
srand(GetTickCount()); //从srand (seed)中指定的seed开始,返回一个[seed, RAND_MAX(0x7fff))间的随机整数。
Sleep((rand() % 10) * 800 + 500);
printf("Slot %d idle\n", n);
return (DWORD)n;
}
6,在一个 GUI 程序中等待
1)我如何在主线 程中等待一个 handle?
Windows 程序中的标准消息循环看起来像这个样子:
while (GetMessage(&msg, NULL, 0, 0,))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
2)MsgWaitForMultipleObjects() 函数
这个函 数非常类似 WaitForMultipleObjects(),但它会在“对象被激发”或“消息到达队列”时被唤醒而返回。MsgWaitForMultipleObjects() 多接受一个参数,允许 指定哪些消息是观察对象。
DWORD MsgWaitForMultipleObjects(
DWORD nCount,
LPHANDLE pHandles,
BOOL fWaitAll,
DWORD dwMilliseconds,
DWORD dwWakeMask
);
参数
dwWakeMask 欲观察的用户输入消息,可以是:
QS_ALLINPUT
QS_HOTKEY
QS_INPUT
QS_KEY
QS_MOUSE
QS_MOUSEBUTTON
QS_MOUSEMOVE
QS_PAINT
QS_POSTMESSAGE
QS_SENDMESSAGE
QS_TIMER
代码: