可等待计时器对象:
可等待计时器对象(1):
1:在开发的时候可能需要:在某些时间点上启动某个线程,按照某种规律来进行线程的启动。Event对象可以决定顺序,但不能帮我们频繁启动线程。
2:可等待计时器对象(WaitableTimer):可以使用CreateWaitableTimer()函数来创建一个可等待计时器对象。
3:CreateWaitableTimer参数:
HANDLE WINAPI CreateWaitableTimer(
_In_opt_ LPSECURITY_ATTRIBUTES lpTimerAttributes, //安全指针
_In_ BOOL bManualReset, //是否为认为置位
_In_opt_ LPCTSTR lpTimerName //定时器名称
);
4:Ex版本与之的差别是多了一个访问权限的控制。
5:可等待计时器对象被创建好后默认是无信号状态的,因此,一开始就WaitForSingleObject会反悔WAIT_TIMEOUT。使用SetWaitableTimer可以使之变为有信号状态。
6:SetWaitableTimer:
BOOL WINAPI SetWaitableTimer(
_In_ HANDLE hTimer, //可以通过CreateWaitableTimer或者Open...得到。
_In_ const LARGE_INTEGER *pDueTime, //以100ns为单位,为FILETIE。到这个时刻,信号才会被触发。
_In_ LONG lPeriod, //每过多久再次启动一次信号,是一个事件间隔。时间单位是ms。
_In_opt_ PTIMERAPCROUTINE pfnCompletionRoutine,
_In_opt_ LPVOID lpArgToCompletionRoutine,
_In_ BOOL fResume
);
可等待计时器对象(2)——自动和手动:
1:一般情况下,可等待计时器对象会使用自动方式,最重要的是我们需要设定的那个时间。
#include <windows.h>
#include <tchar.h>
int main()
{
HANDLE hTimer = CreateWaitableTimer(nullptr, TRUE, nullptr);
LARGE_INTEGER liDueTime;
liDueTime.LowPart = -10000000LL;//1S
SetWaitableTimer(hTimer, &liDueTime, 1000, nullptr, nullptr, FALSE);
if (WaitForSingleObject(hTimer, 1020) == WAIT_TIMEOUT)
_tprintf(TEXT("Time out..."));
else
_tprintf(TEXT("Signal..."));
return 0;
}
可等待计时器对象(3)——APC回调:
1:SetWaitableTimer:
#include <windows.h>
#include <tchar.h>
VOID CALLBACK TimerAPCProc(
_In_opt_ LPVOID lpArgToCompletionRoutine,
_In_ DWORD dwTimerLowValue,
_In_ DWORD dwTimerHighValue
)
{
}
int main()
{
HANDLE hTime = CreateWaitableTimer(nullptr, TRUE, nullptr);
LARGE_INTEGER li = { 0 };
SetWaitableTimer(hTime, &li, 1000, TimerAPCProc, nullptr, FALSE);
SleepEx(INFINITE, TRUE);//之后将会调用APC里面的函数。
return 0;
}
2:上面代码可以将SetWaitableTimer的线程里面把要执行的回调函数押入到调用线程的APC栈里面(线程空闲下来之后会调用APC里面的函数),长这样的方式一般用的很少。特别注意的是,他压入的是调用SetWaitableTimer的这个线程的栈。而不是外面等待的那个线程的栈。