我需要同步访问Windows上的HANDLE吗
Do I need to synchronize access to a HANDLE on Windows?
我有一个可等待计时器的HANDLE,它可以在我的Windows服务中的许多正在运行的线程之间共享,用于API,如CreateWaitableTimer、WaitForSingleObject、SetWaitableTimer和CancelWaiableTimer。
我的问题是,我是否需要通过互斥或关键部分同步对此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);
}
如果全局变量的值可能发生更改,则只需要同步即可从多个线程读取该全局变量。如果您正在创建一个计时器对象,并且句柄的值在此之后再也不会更改,则不需要同步来读取其值。
使用可等待计时器,即在给定计时器句柄的情况下启动计时器并等待该句柄触发,不需要互斥等支持。
从描述中可以清楚地看出,它是专门为线程间操作而设计的,例如,另一个线程可以使用WaitForSingleObject来等待触发计时器事件等。
如果有必要使用互斥锁来保护它,则上述用例
根本不可能,相反,投票是必要的。
如果这还不够推理,这里是页面同步对象的第一句话:
同步对象是一个对象,其句柄可以在一个等待函数,用于协调多个螺纹。
上述页面的子类别包括Mutex、Semaphore、
和等待计时器;一切都在同一水平上。
然而,正如第一句所述,我刚才所说的仅适用于使用它。这些操作的共同点是,您已经有了一个计时器句柄(该句柄不会因上述操作而更改)创建一个新的定时器句柄并将其分配给变量确实会更改变量值。。。
因此,您基本上有两个问题:
1) 如果线程2在线程1创建计时器之前启动计时器,你认为会发生什么?如果在启动Visual Studio之前在Visual Studio中键入一些文本,会发生什么情况?对
2) 句柄只是一个数字ID,可以随意复制和移动。即使在创建之后,计时器也无法保护自己的句柄。在使用过程中对手柄进行任何更改都是不好的。
为此,互斥锁也不是解决方案。它可以保护定时器句柄,但谁来保护互斥句柄。。。?正确的任何同步机制都依赖于在用于同步任何内容之前准备。
问题的真正解决方案是在启动任何线程之前创建计时器并将其分配给句柄;然后将句柄提供给启动的线程(参数或全局变量等)
- Linux的Cpp上的计时器
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- 物理键盘上的触发器按键
- 如何加载(或映射)文件部分的最大大小,但适合在Windows上的RAM
- SSL上的`curl_easy_send`和`curl_asy_recv`:如何处理`CURLE_AGAIN`
- PowerPC ppc64le上的Gcc Woverloaded虚拟错误
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- 集合上的输出迭代器:assign和increment迭代器
- Cuda C++:设备上的Malloc类,并用来自主机的数据填充它
- 为什么我在leetcode上收到AddressSanitizer:地址0x602000000058上的堆缓冲区溢出错误
- 对于set上的循环-获取next元素迭代器
- 如何从棋盘上的箱号中找到行和列
- 为什么除非添加括号,否则构造函数上的模板替换会失败?
- if数组上的随机数
- 向量上的线性搜索
- 位阵列上的快速AND运算
- 无法将 GLFW 库与 Ubuntu 18.04 上的头文件链接
- 为什么一个向量上的多线程操作很慢
- 64位机器上的C++内存对齐
- 我需要同步访问Windows上的HANDLE吗