Component |
Initial # of Threads |
Threads Created |
Threads Destroyed |
How Threads Wait |
What Wakes a Thread |
Timer |
Always 1 |
When first thread pool timer function is called. |
When no timer queue exists. |
Alertable |
Waitable timer is signaled, queuing a user APC. |
Wait |
1 |
One thread for every 63 registered objects. |
When number of registered wait objects is 0. |
WaitForMultiple- ObjectsEx |
Kernel object becomes signaled. |
I/O |
0 |
Heuristic, but some objects that affect it include: some time has passed (in seconds) since a thread was added; a work item is queued with the WT_EXECUTELONG- FUNCTION flag; or the number of queued work items exceeds a threshold amount. |
If the thread has no pending I/O requests and has been idle for a threshold period (a minute or so). |
Alertable |
Queued user APC or completed I/O request. |
Non-I/O |
0 |
Same as I/O. |
If idle for a threshold period (a minute or so). |
GetQueuedCom pletionStatus |
Posted completion status or completed I/O request. The completion port allows at most (2 X the number of CPUs) threads to run concurrently. |
Figure 2 A Timed Message Box
/************************************************************
Module name: TimedMsgBox.cpp
Notices: Written 1999 by Jeffrey Richter
************************************************************/
#define STRICT
#define _WIN32_WINNT 0x0500
#include <windows.h>
/////////////////////////////////////////////////////////////
// The caption of our message box
char g_szCaption[] = "Timed Message Box";
// How many seconds we'll display the message box
int g_nSecLeft = 0;
// This is STATIC window control ID for a message box
#define ID_MSGBOX_STATIC_TEXT 0x0000ffff
/////////////////////////////////////////////////////////////
VOID WINAPI MsgBoxTimeout(PVOID pvContext, BOOLEAN fTimeout) {
// NOTE: Due to a thread race condition, it is possible
// (but very unlikely) that the message box will not be
// created when we get here.
HWND hwnd = FindWindow(NULL, g_szCaption);
if (hwnd != NULL) {
// The window does exist, update the time remaining.
TCHAR sz[100];
wsprintf(sz, "You have %d seconds to respond", g_nSecLeft--);
SetDlgItemText(hwnd, ID_MSGBOX_STATIC_TEXT, sz);
if (g_nSecLeft == 0) {
// The time is up, force the message box to exit
EndDialog(hwnd, IDOK);
}
}
}
/////////////////////////////////////////////////////////////
int WINAPI WinMain (HINSTANCE, HINSTANCE, LPSTR, int) {
// How many seconds we'll give the user to respond
g_nSecLeft = 10;
// Create a multi-shot 1 second timer which begins firing after 1 second.
HANDLE hTimerQTimer;
CreateTimerQueueTimer(&hTimerQTimer, NULL,
MsgBoxTimeout, NULL, 1000, 1000, 0);
// Display the message box
int n = MessageBox(NULL, "You have 10 seconds to respond",
g_szCaption, MB_OK);
// Cancel the timer & delete the timer queue
BOOL f = DeleteTimerQueueTimer(hTimerQ, hTimerQTimer, NULL);
// Let us know if the user responded or if we timed-out.
MessageBox(NULL, (g_nSecLeft == 0) ? "Timeout" : "User responded"),
"Result", MB_OK);
return(0);
}
//////////////////////// End Of File ////////////////////////