一些背景信息:我正在尝试追踪一个导致我头疼的错误。在走了很多弯路之后(请参见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中)内部,显然程序挂起没有任何原因。当我点击继续时,程序就愉快地继续打印一些东西,直到再次被阻止。
你有任何想法吗?
更多信息:
- 据我所知,这个错误只存在于Windows 8.1上。
- 我尝试了VS2013.4和VS2015 RC。
- 我在两台不同的计算机上都可以复现它,运行的是Windows 8.1。
- 其中一台机器已经格式化,RAM、CPU和磁盘都经过了测试(一开始我只能在这台特定的机器上观察到该bug,因此我认为可能是由于故障引起的)
- 我从未在Windows 7上重现过它。
- 修改注释之间的代码以观察该bug可能很有用。当我添加微秒睡眠时,我最终可以在另一台计算机上复制该bug。
- 使用VS2015 RC,我可以通过简单的std::mutex复现相同的行为。但在VS2013中,SRWLOCK似乎是观察该bug的必要条件。
<ppl.h>
中的Concurrency::reader_writer_lock
。这可能是一个破绽,考虑向微软支持团队咨询。 - Hans Passant