一些背景:我正在尝试追踪导致我头痛的错误。经过许多死胡同(见this question)后,我终于得到了这段代码:
#include <thread>
#include <vector>
#include <iosfwd>
#include <sstream>
#include <string>
#include <windows.h>
int main()
{
SRWLOCK srwl;
InitializeSRWLock(&srwl);
for(size_t i=0;i<1000;++i)
{
std::vector<std::thread>threads;
for(size_t j=0;j<100;++j)
{
OutputDebugString(".");
threads.emplace_back([&](){
AcquireSRWLockExclusive(&srwl);
//Code below modifies the probability to see the bug.
std::this_thread::sleep_for(std::chrono::microseconds(1));
std::wstringstream wss;
wss<<std::this_thread::get_id();
wss.str();
//Code above modifies the probability to see the bug.
ReleaseSRWLockExclusive(&srwl);});
}
for(auto&t:threads){t.join();}
OutputDebugString((std::to_string(i)+"\n").data());
}
return 0;
}
当我在VS 2013调试器中运行此代码时,程序将挂起如下输出:
....................................................................................................0
....................................................................................................1
....................................................................................................2
...........................
奇怪的是,如果我暂停调试器并检查发生了什么,其中一个线程在AcquireSRWLockExclusive内(在NtWaitForAlertByThreadId中)显然没有理由为什么程序挂起。当我点击继续时,程序会愉快地继续并打印更多东西,直到它再次被阻止。
你有什么想法吗?
更多信息:
答案 0 :(得分:4)
此问题是由2014年春季Windows 8.1更新中引入的操作系统调度程序错误引起的。此问题的修补程序已于2015年5月发布,可在https://support.microsoft.com/en-us/kb/3036169处获得。
答案 1 :(得分:1)
对我来说,它看起来像是Windows操作系统中的一个错误,我有不同的代码变种,在2014年4月更新后,在Win 8.1 / Server 2012R2的调试器下使用新的Vista原语。还有一些线程池等待功能也挂起。看起来它主要与等待/锁定时的其他线程完成执行相关联。以下是在NtWaitForAlertByThreadId()中始终挂在调试器下的简单代码:
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#pragma optimize("",off)
VOID CALLBACK _WorkCallback(PTP_CALLBACK_INSTANCE Instance, PVOID pUser, PTP_WORK Work)
{
for (int i = 0; i < INT_MAX / 256; i++) {}
}
DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
for (int i = 0; i < INT_MAX / 256; i++) {}
return 0;
}
#pragma optimize("",on)
int _tmain(int argc, _TCHAR* argv[])
{
LONGLONG c = 0;
while(!_kbhit())
{
PTP_WORK ptpw = CreateThreadpoolWork(&_WorkCallback, NULL, NULL);
if (ptpw != NULL)
{
for(long i = 0; i < 3; i++) SubmitThreadpoolWork(ptpw);
CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
WaitForThreadpoolWorkCallbacks(ptpw, FALSE);
CloseThreadpoolWork(ptpw);
}
printf("%I64d \r", c++);
}
_getch();
return 0;
}
不幸的是我不知道在哪里向微软报告。