C++ - std::thread 在执行时崩溃

C++ - std::thread crashes upon execution(C++ - std::thread 在执行时崩溃)
本文介绍了C++ - std::thread 在执行时崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

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

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

void service(){}/* 连接到服务器 */无效连接到服务器(){cout<<"~客户端~
" <<结束;std::thread 服务器连接(服务);}

当程序调用 connectToServer() 时,它在调用语句 std::thread serverConnect(service); 处中断,调用堆栈如下:

msvcr110.dll!_crt_debugger_hook(int _Reserved) Line 60 Cmsvcr110.dll!_call_reportfault(int nDbgHookCode, unsigned long dwExceptionCode, unsigned long dwExceptionFlags) 第 152 行 C++msvcr110.dll!abort() 第 90 行 Cmsvcr110.dll!terminate() 第 96 行 C++IRC.exe!connectToServer() 第 449 行 C++IRC.exe!handleKeypress(unsigned char key, int x, int y) 第 936 行 C++glut32.dll!1000e054() 未知[下面的帧可能不正确和/或丢失,没有为 glut32.dll 加载符号]glut32.dll!1000d5de() 未知user32.dll!753962fa() 未知user32.dll!75396d3a() 未知user32.dll!75396ce9() 未知user32.dll!753a0d27() 未知user32.dll!753a0d4d() 未知opengl32.dll!18f160fb() 未知user32.dll!753962fa() 未知user32.dll!75396d3a() 未知user32.dll!75396ce9() 未知user32.dll!753977c4() 未知user32.dll!753bd62a() 未知user32.dll!75397bca() 未知glut32.dll!10004970() 未知glut32.dll!10004a7a() 未知glut32.dll!1000491f() 未知IRC.exe!main(int argc, char * * argv) 第 1683 行 C++IRC.exe!__tmainCRTStartup() 第 536 行 Ckernel32.dll!7551338a() 未知ntdll.dll!77049f72() 未知ntdll.dll!77049f45() 未知

该程序在没有线程调用语句的情况下完美运行.另外,我的 VS 环境运行这样的简单示例线程程序没有问题:

#include #include <线程>使用命名空间标准;//这个函数会被一个线程调用void call_from_thread() {std::cout <<你好,世界"<<std::endl;}int main() {//启动一个线程线程 t1(call_from_thread);系统(暂停");返回0;}

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

解决方案

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

<块引用>

~thread();

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

有多种可能的修复方法:

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

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

I am using VS2012 and I can't execute a thread in my program without it crashing. It should be noted that my program contains OpenGL and SOIL.

I simply call a blank thread, a function with no statements, in one of my functions and it immediately crashes:

void service(){

}

/* Connect to server */
void connectToServer(){

    cout << "~CLIENT~
" << endl;

    std::thread serverConnect(service);
}

When the program calls connectToServer() it breaks at the call statement std::thread serverConnect(service); with the following call-stack:

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

The program works perfectly without the thread call statement. Also, my VS environment has no problem running simple example thread programs like this one:

#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;
}

It's only when I use threads in my program that it crashes.

解决方案

Destroying a std::thread object associated with a joinable() thread causes std::terminate() to be called. §30.3.1.3 [thread.thread.destr]:

~thread();

If joinable(), calls std::terminate(). Otherwise, has no effects. [ Note: Either implicitly detaching or joining a joinable() thread in its destructor could result in difficult to debug correctness (for detach) or performance (for join) bugs encountered only when an exception is raised. Thus the programmer must ensure that the destructor is never executed while the thread is still joinable. —end note ]

There are a multitude of possible fixes:

  • Allocate the thread on the heap and having your function return a smart pointer to the thread object
  • Or have it return a std::thread (move serverConnect into the return value)
  • Move serverConnect into something that won't be destroyed when connectToServer() returns (e.g., a global variable)
  • join() the thread before you return
  • detach() the thread before you return

The correct choice depends on your particular use case.

这篇关于C++ - std::thread 在执行时崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

相关文档推荐

Prevent class inheritance in C++(防止 C++ 中的类继承)
Why should I declare a virtual destructor for an abstract class in C++?(为什么要在 C++ 中为抽象类声明虚拟析构函数?)
Why is Default constructor called in virtual inheritance?(为什么在虚拟继承中调用默认构造函数?)
C++ cast to derived class(C++ 转换为派生类)
C++ virtual function return type(C++虚函数返回类型)
Is there any real risk to deriving from the C++ STL containers?(从 C++ STL 容器派生是否有任何真正的风险?)