【问题标题】:C++ - std::thread crashes upon executionC++ - std::thread 在执行时崩溃
【发布时间】:2020-02-13 17:13:12
【问题描述】:

我正在使用 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;
}

只有当我在程序中使用线程时才会崩溃。

【问题讨论】:

  • 你join() 线程了吗?

标签: c++ multithreading opengl


【解决方案1】:

销毁与joinable() 线程关联的std::thread 对象会导致调用std::terminate()。 §30.3.1.3 [thread.thread.destr]:

~thread();

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

有多种可能的修复方法:

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

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

【讨论】:

  • 这在代码方面是什么意思,如何修复代码?
  • 这意味着您不能在堆栈上创建线程对象,然后立即使其超出范围。你需要把它保存在某个地方。 T.C.为您提供了许多可能的解决方案。
猜你喜欢
  • 1970-01-01
  • 2011-01-19
  • 2021-10-04
  • 1970-01-01
  • 2023-03-08
  • 1970-01-01
  • 2019-10-16
  • 2010-11-06
相关资源
最近更新 更多