C++std::线程在执行时崩溃

C++ - std::thread crashes upon execution

本文关键字:崩溃 执行 线程 C++std      更新时间:2023-10-16

我使用的是VS2012,我无法在程序中执行线程而不崩溃。需要注意的是,我的程序包含OpenGL和SOIL。

我只需在我的一个函数中调用一个空线程,一个没有语句的函数,它就会立即崩溃:

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();

如果是joinable(),则调用std::terminate()。否则,没有效果。注意:隐式分离或加入joinable()线程在其析构函数中可能导致调试困难遇到正确性(用于分离)或性能(用于联接)错误仅当引发异常时。因此,程序员必须确保当线程仍然是可连接的时,析构函数永远不会被执行。--尾注]

有许多可能的修复方法:

  • 在堆上分配线程,并让函数返回一个指向线程对象的智能指针
  • 或者让它返回一个std::thread(将serverConnect移到返回值中)
  • serverConnect移动到connectToServer()返回时不会被破坏的内容中(例如,全局变量)
  • join()返回前的线程
  • detach()返回前的线程

正确的选择取决于您的特定用例。