WaitForSingleObject()的早期唤醒...?

时间:2019-07-08 19:25:49

标签: windows multithreading time

我在MS docs网站(未真正解决的地方)和SO中的所有内容都读过,都说Windows WaitForSingleObject()不受虚假唤醒的影响,它至少等待指定的时间,甚至更长。但是,我的测试表明情况并非如此,事实上,几乎总是发生早期唤醒。 “常识”是错误的,我只需要添加循环来处理早期的唤醒,还是我做错了什么,我需要继续努力以找出答案?

不幸的是,完整的代码太复杂了,无法在此处发布,但是我有两个不同的线程,每个线程都有自己的事件,通过以下方式创建:

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。几乎每次返回的值都太短时:2ms等待可能花费700us以上,而100ms等待花费大约93毫秒在大约7次尝试中只有一次,经过的时间将> 100ms。以下是一些示例输出:

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,这是一个使用Windows10上运行的Visual Studio 2017编译的C ++程序。它是使用Google Test的单元测试程序,没有图形界面:仅命令行。

0 个答案:

没有答案