我有waitable timer的HANDLE,可以在我的Windows服务中为许多正在运行的线程共享CreateWaitableTimer,WaitForSingleObject,SetWaitableTimer和{ {3}}
我的问题是,我是否需要通过互斥锁或关键部分同步访问(读/写)此HANDLE本身?
编辑: 好的,我想我需要澄清一下(使用代码):
//Say, I have a global handle
HANDLE ghWaitableTimer = NULL; //Originally set to NULL
...
//Thread one
if(!ghWaitableTimer)
{
ghWaitableTimer = ::CreateWaitableTimer(NULL, FALSE, NULL);
}
...
//Thread two
if(ghWaitableTimer)
{
::SetWaitableTimer(ghWaitableTimer, &liWhen, 0, NULL, NULL, FALSE);
}
...
//Thread three
if(ghWaitableTimer)
{
::WaitForSingleObject(ghWaitableTimer, INFINITE);
}
或者我需要这样做:
//Say, I have a global handle
HANDLE ghWaitableTimer = NULL; //Originally set to NULL
CRITICAL_SECTION CriticalSection; //Must be initialized before it's used
...
//Thread one
::EnterCriticalSection(&CriticalSection);
if(!ghWaitableTimer)
{
ghWaitableTimer = ::CreateWaitableTimer(NULL, FALSE, NULL);
}
::LeaveCriticalSection(&CriticalSection);
...
//Thread two
::EnterCriticalSection(&CriticalSection);
HANDLE hTimer = ghWaitableTimer;
::LeaveCriticalSection(&CriticalSection);
if(hTimer)
{
::SetWaitableTimer(hTimer, &liWhen, 0, NULL, NULL, FALSE);
}
...
//Thread three
::EnterCriticalSection(&CriticalSection);
HANDLE hTimer = ghWaitableTimer;
::LeaveCriticalSection(&CriticalSection);
if(hTimer)
{
::WaitForSingleObject(hTimer, INFINITE);
}
答案 0 :(得分:1)
使用等待计时器,即。在给定计时器句柄并等待使用该句柄触发的情况下启动计时器,不需要互斥锁等支持。
从描述中可以清楚地看出,它是专门用于线程间操作的,例如。另一个线程可以使用WaitForSingleObject来等待触发定时器事件等等
如果有必要用互斥锁保护它,上述用例
根本不可能,相反,投票是必要的。
如果这还不够推理,请点击页面Synchronization Objects的第一句话:
同步对象是可以在其中指定句柄的对象 其中一个等待函数来协调多个执行 线程。
...和所提到的页面的子类别是例如。 Mutex,Semaphore,
和等待计时器;一切都在同一水平上。
然而,我刚才所说的只对第一句中所述的使用有效。这些操作的共同之处在于您已经拥有一个计时器句柄(所述操作不会更改)。 创建新的计时器句柄并将其分配给变量会改变变量值...
所以,你基本上有两个问题:
1)如果线程2在线程1创建之前启动计时器,您认为会发生什么?如果在启动Visual Studio之前在Visual Studio中键入一些文本会发生什么?右。
2)句柄只是一个数字ID,可以根据需要复制和移动。即使在创建之后,计时器也无法保护它自己的手柄。在使用过程中对手柄进行任何更改都是不好的。
为此,互斥量也不是解决方案。它可以保护定时器手柄,但谁保护互斥锁手柄...?对。任何同步机制都依赖于在用于同步任何内容之前准备。
您的问题的真正解决方案是创建计时器并在启动任何线程之前将其分配给句柄;然后为启动的线程(参数或全局变量等)提供句柄。
答案 1 :(得分:1)
如果该变量的值可能发生变化,您只需要同步从多个线程读取全局变量。如果要创建单个计时器对象,并且句柄的值在此之后永远不会更改,则不需要同步来读取其值。