windows - WaitForSingleObject() 中的早期唤醒...?
问题描述
我在 MS 文档站点(没有真正解决)和 SO 中读到的所有内容都表示,WindowsWaitForSingleObject()
不会受到虚假唤醒的影响,它至少会等待提供的时间,甚至可能更长。然而,我的测试表明这不是真的,事实上早醒几乎总是发生。“常识”是错误的,我只需要添加循环来处理早期唤醒,还是我做错了什么,我需要继续努力解决这个问题?
不幸的是,完整的代码太复杂了,无法在这里发布,但我有两个不同的线程,每个线程都有自己的事件,通过以下方式创建:
event = CreateEventA(NULL, false, false, NULL);
(事件是线程局部变量)。我有一个互斥锁,用于确保两个线程几乎同时开始运行。
在我调用的每个线程WaitForSingleObject()
中。在这个特定的测试中,我从不调用SetEvent()
,所以完成的唯一方法是通过超时,返回代码显示这就是发生的情况。然而,实际花费的等待时间变化很大,90% 的时间少于我要求的时间。我已经对此进行QueryPerformanceCounter()
了检测,以检测在这里花费了多长时间,这是错误的。这是检测代码:
LARGE_INTEGER freq, ctr1, ctr2;
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&ctr1);
DWORD ret = WaitForSingleObject(event, tmoutMs);
QueryPerformanceCounter(&ctr2);
uint64_t elapsed = ((uint64_t)ctr2.QuadPart - (uint64_t)ctr1.QuadPart) * 1000000ULL / (uint64_t)freq.QuadPart;
(这里elapsed
以微秒为单位,只是为了更具体一点)然后我打印出这个信息。在一个线程tmoutMs
中是 2,而在另一个线程tmoutMs
中是 100。几乎每次返回的值都太短:2 毫秒的等待可能需要 700 毫秒以上的任何时间,而 100 毫秒的等待时间可能需要大约 93 毫秒。只有在 7 次左右的尝试中,经过的时间才会 > 100 毫秒。以下是一些示例输出:
event=104: pause(tmoutMs=2) => ret=258 elapsed us=169, ms=0
event=112: pause(tmoutMs=100) => ret=258 elapsed us=93085, ms=93
event=104: pause(tmoutMs=2) => ret=258 elapsed us=427, ms=0
event=112: pause(tmoutMs=100) => ret=258 elapsed us=94002, ms=94
event=104: pause(tmoutMs=2) => ret=258 elapsed us=3317, ms=3
event=112: pause(tmoutMs=100) => ret=258 elapsed us=96840, ms=96
event=104: pause(tmoutMs=2) => ret=258 elapsed us=11461, ms=11
event=112: pause(tmoutMs=100) => ret=258 elapsed us=105189, ms=105
如预期的那样,返回码始终是 WAIT_TIMEOUT。
这是合理的,即使它没有记录(或者它记录在我找不到的某个地方),我只需要自己循环处理早期唤醒吗?
FWIW,这是一个用 Visual Studio 2017 编译的 C++ 程序,在 Windows10 上运行。它是一个使用 Google Test 的单元测试程序,没有图形界面:它只是命令行。
解决方案
推荐阅读
- excel - 回执 Lotus Notes
- c# - .net core 3.1 中的 System.Web.Helpers.Json.Encode() 使用什么替代方法?
- sql-server - 安装 Microsoft SQL Server 2014 的问题
- cakephp - 使用 cakephp 1.2 保存具有多个关系的数据
- ubuntu - 在golang中提取tarball时丢失文件
- java - recyclerview 的问题,我想为每个按钮添加声音,但我不知道如何
- google-apps-script - 结合两个必须一个接一个工作的功能(带触发器)
- java - Recyclerview 使用 SearchView 过滤后位置错误
- c# - LINQ 方法,它按我发送的列名动态排序数据
- php - Laravel“下一个错误异常:遇到格式不正确的数值”php-7.4