我使用的是VS2012,我无法在我的程序中执行一个线程而不使它崩溃。 需要注意的是,我的程序包含OpenGL和土壤。
我只是在我的一个函数中调用一个空线程,一个没有语句的函数,它立即崩溃:
void service(){
}
/* Connect to server */
void connectToServer(){
cout << "~CLIENT~\n" << endl;
std::thread serverConnect(service);
}
当程序调用ConnectToServer()
时,它在调用语句std::thread serverConnect(service);
处中断,调用堆栈如下:
msvcr110.dll!_crt_debugger_hook(int _Reserved) Line 60 C
msvcr110.dll!_call_reportfault(int nDbgHookCode, unsigned long dwExceptionCode, unsigned long dwExceptionFlags) Line 152 C++
msvcr110.dll!abort() Line 90 C
msvcr110.dll!terminate() Line 96 C++
IRC.exe!connectToServer() Line 449 C++
IRC.exe!handleKeypress(unsigned char key, int x, int y) Line 936 C++
glut32.dll!1000e054() Unknown
[Frames below may be incorrect and/or missing, no symbols loaded for glut32.dll]
glut32.dll!1000d5de() Unknown
user32.dll!753962fa() Unknown
user32.dll!75396d3a() Unknown
user32.dll!75396ce9() Unknown
user32.dll!753a0d27() Unknown
user32.dll!753a0d4d() Unknown
opengl32.dll!18f160fb() Unknown
user32.dll!753962fa() Unknown
user32.dll!75396d3a() Unknown
user32.dll!75396ce9() Unknown
user32.dll!753977c4() Unknown
user32.dll!753bd62a() Unknown
user32.dll!75397bca() Unknown
glut32.dll!10004970() Unknown
glut32.dll!10004a7a() Unknown
glut32.dll!1000491f() Unknown
IRC.exe!main(int argc, char * * argv) Line 1683 C++
IRC.exe!__tmainCRTStartup() Line 536 C
kernel32.dll!7551338a() Unknown
ntdll.dll!77049f72() Unknown
ntdll.dll!77049f45() Unknown
程序在没有线程调用语句的情况下工作得很完美。 而且,我的VS环境运行像下面这样的简单示例线程程序也没有问题:
#include <iostream>
#include <thread>
using namespace std;
//This function will be called from a thread
void call_from_thread() {
std::cout << "Hello, World" << std::endl;
}
int main() {
//Launch a thread
thread t1(call_from_thread);
system("pause");
return 0;
}
只有当我在我的程序中使用线程时,它才会崩溃。
销毁与joinable()
线程关联的std::thread
对象会导致调用std::terminate()
。 §30.3.1.3[Thread.Thread.Destr]:
~thread();
如果joinable()
,则调用std::terminate()
。 否则,没有任何影响。 [注意:在析构函数中隐式分离或联接joinable()
线程可能导致仅在引发异常时才遇到的难以调试的正确性(对于分离)或性能(对于联接)错误。因此,程序员必须确保线程仍可联接时从不执行析构函数。-结束注意]
有许多可能的修复方法:
std::thread
(将ServerConnect
移到返回值中)ServerConnect
移动到当ConnectToServer()
返回(例如全局变量)时不会被破坏的内容中join()
返回之前的线程在返回之前分离()
线程正确的选择取决于您的特定用例。