多线程同步-可等待的计时器内核对象

1.简介

它们会在某个指定的时间触发,或每隔一段时间触发一次。它们通常用来在某个时间执行一些操作。

HANDLE CreateWaitableTimer
(
   PSECURITY_ATTRIBUTES psa,
   BOOL fManualReset,
   PCTSTR pszName
);
  • psa:指向SECURITY_ATTRIBUTES结构的指针。
  • fManualReset:告诉系统是创建一个人工重置的计时器(TRUE)还是创建一个自动重置的事计时器(FALSE)。
  • pszName:对象的名称。

  • 人工重置的定时器信号通知时,等待该定时器的所有线程均变为可调度线程。
  • 自动重置的定时器信号通知时,只有一个等待的线程变为可调度线程。

进程调用OpenWaitableTimer函数,可以获得一个已经存在的可等待计时器的句柄,该句柄与当前进程相关联。

HANDLE OpenWaitableTimer
(
   DWORD dwDesiredAccess,
   BOOL bInheritHandle,
   PCTSTR pszName
);

在创建的时候,可等待定时器对象总是在未通知状态中创建(不像事件对象那样,可以让我们指定)。当我们想要触发计时器的时候,必须调用SetWaitableTimer。

BOOL SetWaitableTimer
(
   HANDLE hTimer,
   const LARGE_INTEGER *pDueTime,
   LONG lPeriod,
   PTIMERAPCROUTINE pfnCompletionRoutine,
   PVOID pvArgToCompletionRoutine,
   BOOL fResume
);
  • hTimer参数用于指明你要设置的定时器。
  • pDueTime和lPeriod两个参数是一起使用的。PDueTimer参数用于指明定时器何时应该第一次报时,而lPeriod参数则用于指明此后定时器应该间隔多长时间报时一次。
  • fResume:它可以用于支持暂停和恢复的计算机。通常可以为该参数传递FALSE。

2.示例

int main()
{
    HANDLE hTimer = NULL;
    LARGE_INTEGER liDueTime;
 
    liDueTime.QuadPart = -100000000LL;
 
    // Create an unnamed waitable timer.
    hTimer = CreateWaitableTimer(NULL, TRUE, NULL);
    if (NULL == hTimer)
    {
        printf("CreateWaitableTimer failed (%d)\n", GetLastError());
        return 1;
    }
 
    printf("Waiting for 10 seconds...\n");
 
    // Set a timer to wait for 10 seconds.
    if (!SetWaitableTimer(hTimer, &liDueTime, 0, NULL, NULL, 0))
    {
        printf("SetWaitableTimer failed (%d)\n", GetLastError());
        return 2;
    }
 
    // Wait for the timer.
 
    if (WaitForSingleObject(hTimer, INFINITE) != WAIT_OBJECT_0)
        printf("WaitForSingleObject failed (%d)\n", GetLastError());
    else printf("Timer was signaled.\n");
 
    return 0;
}

运行结果:等待10s结束

多线程同步-可等待的计时器内核对象_第1张图片

在调用SetWaitableTimer的时候,我们除了能给计时器第一次触发的时间指定一个绝对时间,还可以指定一个相对时间。只要在PDueTimer参数中传入负值。传入的值必须是100纳秒的整数倍。

1s = 1000ms = 1000000µs = 100000000ns 。

通常情况下,你可能想要一个一次报时的定时器,它只是发出一次报时信号,此后再也不发出报时信号。若要做到这一点,只需要为lPeriod参数传递0即可。然后可以调用CloseHandle函数,关闭定时器,或者再次调用SetWaitableTimer函数,重新设置时间,为它规定一个需要遵循的新条件。

你可能感兴趣的:(#,Windows核心编程,windows,c++,开发语言)