线程同步对象之可等待定时器

线程同步对象之可等待定时器

——每周杂谈 第003篇

作者:Tocy    时间:2012-05-26

同步对象(synchronization object)是指其句柄能够被wait函数族(例如 WaitForSingleObject函数)使用,并用于控制多线程执行的对象。通常有以下几个同步对象:

表格 1 同步对象类型

类型

描述

Event 事件

通知一个或者多个线程某个事件发生,Event Objects.

Mutex

互斥量

同一时间只能被一个线程获得,保证线程用于对共享资源互斥性访问,Mutex Objects.

Semaphore

信号量

保持[0, maximum]范围内的一个数值,可以限制同时访问共享资源的线程数量,Semaphore Objects.

Waitable timer

可等待计时器

在设定的时间间隔到达时通知一个或者多个线程,Waitable Timer Objects.

相信对于多数人,事件、互斥量和信号量都是非常熟悉的,这里着重介绍下可等待计时器。如果想了解前三个同步对象的使用,请参考MSDN或者其他文章。

同步对象亦可用于多进程之间的通信(IPC)。

当约定的时间到达,可等待计时器(Waitable timer)的状态会被设置成signaled(已通知状态,或触法状态)。Windows下可等待计时器有以下几种:

表格 2 等待计时器类型

对象

说明

Manual-reset timer

手工重置计时器

计时器会保持signaled,除非调用SetWaitableTimer新建一个约定时间。

Synchronization timer

同步计时器

计时器在线程完成wait操作之前保持singled,也就是说计时器的状态重置是在wait函数操作完成之后进行的。

Periodic timer

周期性计时器

按照指定的周期重新激活计时器,除非计时器被重置或者取消。周期性计时器可以是以上两种类型的任意一种。

在MSDN(http://msdn.microsoft.com/en-us/library/ms687012(v=vs.85))中,针对移动设备不推荐使用周期性计时器,尤其是高频率的(低时间间隔)的周期性计时器。推荐优先使用非周期计时器,或者将计时器周期设置为不小于1秒。

 

可等待计时器用法跟事件、互斥量、信号量等同步对象类似,首先创建计时器(使用 CreateWaitableTimer or CreateWaitableTimerEx 函数),在其他进程中可以使用OpenWaitableTimer函数来打开一个存在的计时器(使用该计时器的名字即可)。所用拥有计时器句柄的线程都可以使用wait函数族来等待该其状态改变。使用 SetWaitableTimer函数来激活计时器。使用CancelWaitableTimer函数可以将计时器置位(non-signaled),重置计时器调用SetWaitableTimer函数。当不再使用计时器对象时,使用CloseHandler来关闭即使句柄既可以。

说明:

1. CreateWaitableTimer函数可以决定计时器类型(手中重置或者同步计时器)。

函数原型:

HANDLE WINAPI CreateWaitableTimer(

__in_opt  LPSECURITY_ATTRIBUTES lpTimerAttributes,

__in      BOOL bManualReset,            // 这个参数决定计时器类型

__in_opt  LPCTSTR lpTimerName

);

返回值:函数成功则返回计时器对象句柄,失败则返回NULL。

2.  SetWaitableTimer函数可以激活特定可等待计时器,原型如下:

BOOL WINAPI SetWaitableTimer(

__in      HANDLE hTimer,                    // 计时器句柄

__in      const LARGE_INTEGER *pDueTime,    // 计时器状态改变的等待时间

__in      LONG lPeriod,                        // 周期性计时器的周期

__in_opt  PTIMERAPCROUTINE pfnCompletionRoutine,

__in_opt  LPVOID lpArgToCompletionRoutine,

__in      BOOL fResume

);

 

详细参数意义:http://msdn.microsoft.com/en-us/library/ms686289(v=vs.85)

 

下面是MSDN中给出的实例代码:

#include <windows.h>

#include <stdio.h>

 

int main()

{

HANDLE hTimer = NULL;

LARGE_INTEGER liDueTime;    // 以100纳秒为分割

 

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;

}

 

注:版权所有,请勿用于商业用途,转载请注明原文地址。本人保留所有权利。

posted @ 2012-06-03 09:59  Tocy  阅读(537)  评论(0编辑  收藏  举报