VC++ 11中的std::线程类导致随机崩溃。有什么解决方法吗?[英] std::thread class in VC++ 11 causes random crashes. Any workarounds?

本文是小编为大家收集整理的关于VC++ 11中的std::线程类导致随机崩溃。有什么解决方法吗?的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我在Visual Studio 11开发人员预览中遇到了一个错误,至少我认为这是一个错误并报告了它,但是我很感兴趣是否有人知道解决方法.

当我使用std::thread类创建多于一个线程时,它会导致应用程序崩溃.有时会引起异常,有时会导致访问违规,有时会起作用.复制错误的代码如下:

#include <iostream>
#include <thread>
#include <vector>

#include <Windows.h>

int _tmain(int argc, _TCHAR* argv[])
{
 std::vector<std::thread*> threads;
 for(int i = 0; i < 10; i++)
 {
   threads.push_back(new std::thread([i]
     {
       /*std::cout << "thread " << i << std::endl;*/
       /* whatever else that is thread safe, or even an empty lambda */
     }));
 }

 for(int i = 0; i < 10; i++)
 {
   threads[i]->join();
   delete threads[i];
 }

 return 0;
}

使用静态或动态CRT库(所有这些都是多线程)都没关系.

推荐答案

这是一个已知问题.请参阅以下连接错误:

std :: thread with error with error" f:\ dd \ vctools \ crt_bld \ crt_bld \ self_x86 \ sutex.cpp(206):解锁未拥有的静音"

在该错误报告的评论中,斯蒂芬说:"我们已经修复了它,该修复程序将在VC11中可用." (我不知道该修复程序是否存在于VC11 Beta中.我们将在下周找到.)

其他推荐答案

我在VS11 DEV预览中没有任何问题.以下对我有用.我必须使用略有不同的构建设置,因为我必须删除对_TCHAR的引用.如果这不是一个新错误,因为开发预览,那么可能会弄乱构建设置会有所帮助.我正在使用的刮擦项目应该主要是默认设置.我记得的唯一变化是手动禁用和删除预编译的标题内容,因为在项目创建中,请取消选中该复选框.

#include <iostream>
#include <thread>
#include <vector>

#include <Windows.h>

int main(int argc, char* argv[])
{
 std::vector<std::thread*> threads;
 for(int i = 0; i < 10; i++)
 {
   threads.push_back(new std::thread([i]
     {
       std::cout << "thread " << i << std::endl;
       /* whatever else that is thread safe, or even an empty lambda */
     }));
 }

 for(int i = 0; i < 10; i++)
 {
   threads[i]->join();
   delete threads[i];
 }

 return 0;
}

您也不需要指针.您可以使用std::vector<std::thread>(或std::array),因为std::thread是可移动的.

std::array<std::thread,10> threads;
for(int i = 0; i < threads.size(); i++)
    threads[i] = std::thread([i] { std::cout << "thread " << i << std::endl; });

for(int i = 0; i < 10; i++)
    threads[i].join();

本文地址:https://www.itbaoku.cn/post/488878.html

问题描述

I've encounter a bug in Visual Studio 11 Developer Preview, at least I think it is a bug and reported it, but I'm interested whether someone know a workaround.

When I use std::thread class to create more then one thread it causes application to crash. Sometimes it throws exception, sometimes it causes access violation and sometimes it works. Code that reproduces the bug looks like this:

#include <iostream>
#include <thread>
#include <vector>

#include <Windows.h>

int _tmain(int argc, _TCHAR* argv[])
{
 std::vector<std::thread*> threads;
 for(int i = 0; i < 10; i++)
 {
   threads.push_back(new std::thread([i]
     {
       /*std::cout << "thread " << i << std::endl;*/
       /* whatever else that is thread safe, or even an empty lambda */
     }));
 }

 for(int i = 0; i < 10; i++)
 {
   threads[i]->join();
   delete threads[i];
 }

 return 0;
}

It doesn't matter whether the static or dynamic CRT libraries are used (all of them are multi-threaded)..

bug report

Stacktrace (thrown exception, unlocking unowned mutex):

test.exe!_NMSG_WRITE(int rterrnum) Line 217 C
test.exe!abort() Line 62    C
test.exe!_Thrd_abort(const char * msg) Line 111 C
test.exe!_Mtx_unlock(_Mtx_internal_imp_t * * mtx) Line 206  C++
test.exe!_Save_state(_Mtx_internal_imp_t * * mtx, _Mtx_state * state) Line 266  C++
test.exe!do_wait(_Cnd_internal_imp_t * * cond, _Mtx_internal_imp_t * * mtx, const xtime * target) Line 103  C
test.exe!_Cnd_wait(_Cnd_internal_imp_t * * cond, _Mtx_internal_imp_t * * mtx) Line 198  C
test.exe!std::_Cnd_waitX(_Cnd_internal_imp_t * * _Cnd, _Mtx_internal_imp_t * * _Mtx) Line 94    C++
test.exe!std::_Pad::_Launch(_Thrd_imp_t * _Thr) Line 97 C++
test.exe!??$_Launch@V?$_Bind@$0A@XV<lambda_1B7F0477D0C0EDFD>@?4?wmain@U_Nil@std@@U23@U23@U23@U23@U23@U23@@std@@@std@@YAXPAU_Thrd_imp_t@@ABV?$_Bind@$0A@XV<lambda_1B7F0477D0C0EDFD>@?4?wmain@U_Nil@std@@U23@U23@U23@U23@U23@U23@@0@@Z(_Thrd_imp_t * _Thr, const std::?$_Bind@$0A@XV<lambda_1B7F0477D0C0EDFD>@?4?wmain@U_Nil@std@@U23@U23@U23@U23@U23@U23@ & _Tg) Line 207    C++
test.exe!main::main(wmain::__l5::<lambda_1B7F0477D0C0EDFD> _Fx) Line 47 C++
test.exe!wmain(int argc, wchar_t * * argv) Line 17  C++
test.exe!__tmainCRTStartup() Line 238   C
test.exe!wmainCRTStartup() Line 168 C
kernel32.dll!76d7339a() Unknown
[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]  
ntdll.dll!77cc9ef2()    Unknown
ntdll.dll!77cc9ec5()    Unknown

Stacktrace (access violation):

test.exe!_Mtx_unlock(_Mtx_internal_imp_t * * mtx) Line 218  C++
test.exe!std::_Mtx_unlockX(_Mtx_internal_imp_t * * _Mtx) Line 84    C++
test.exe!std::_Pad::_Release() Line 105 C++
test.exe!?_Run@?$_LaunchPad@V?$_Bind@$0A@XV<lambda_1B7F0477D0C0EDFD>@?4?wmain@U_Nil@std@@U23@U23@U23@U23@U23@U23@@std@@@std@@CAIPAV12@@Z(std::?$_LaunchPad@V?$_Bind@$0A@XV<lambda_1B7F0477D0C0EDFD>@?4?wmain@U_Nil@std@@U23@U23@U23@U23@U23@U23@@std@@ * _Ln) Line 195  C++
test.exe!?_Go@?$_LaunchPad@V?$_Bind@$0A@XV<lambda_1B7F0477D0C0EDFD>@?4?wmain@U_Nil@std@@U23@U23@U23@U23@U23@U23@@std@@@std@@UAEIXZ() Line 187   C++
test.exe!_Call_func(void * _Data) Line 52   C++
test.exe!_callthreadstartex() Line 308  C
test.exe!_threadstartex(void * ptd) Line 291    C
kernel32.dll!76d7339a() Unknown
[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]  
ntdll.dll!77cc9ef2()    Unknown
ntdll.dll!77cc9ec5()    Unknown

Thanks!

推荐答案

This is a known issue. See the following Connect bug:

std::thread crashes with error "f:\dd\vctools\crt_bld\self_x86\crt\src\thr\mutex.cpp(206): unlock of unowned mutex"

In the comments of that bug report, Stephan says, "We've fixed it, and the fix will be available in VC11." (Whether the fix will be present in the VC11 Beta, I do not know. We'll find out next week.)

其他推荐答案

I haven't had any problems with threads in the VS11 dev preview. The following works for me. I must be using slightly different build settings because I had to remove the references to _TCHAR. If it's not a new bug since the dev preview then maybe messing around with the build settings will help. The scratch project I'm using should mostly be the default. The only thing I remember change was manually disabling and deleting the precompiled header stuff, because unchecking that check box in the project creation wizard never does anything.

#include <iostream>
#include <thread>
#include <vector>

#include <Windows.h>

int main(int argc, char* argv[])
{
 std::vector<std::thread*> threads;
 for(int i = 0; i < 10; i++)
 {
   threads.push_back(new std::thread([i]
     {
       std::cout << "thread " << i << std::endl;
       /* whatever else that is thread safe, or even an empty lambda */
     }));
 }

 for(int i = 0; i < 10; i++)
 {
   threads[i]->join();
   delete threads[i];
 }

 return 0;
}

Also you don't need pointers. You can use std::vector<std::thread> (or std::array) because std::thread is movable.

std::array<std::thread,10> threads;
for(int i = 0; i < threads.size(); i++)
    threads[i] = std::thread([i] { std::cout << "thread " << i << std::endl; });

for(int i = 0; i < 10; i++)
    threads[i].join();