尝试在我的基类中启动线程时,Visual Studio 由于调试错误而中止我的程序

When trying to start a thread in my base class, Visual Studio aborts my program due to a debug error

本文关键字:我的 调试 于调试 错误 程序 Visual 基类 启动 线程 Studio      更新时间:2023-10-16

当我从基类启动线程时,它运行良好,然后Visual Studio告诉我存在中止错误。

我正在使用Visual Studio Community 19,当我调试程序时,Visual Studio在我创建新线程和 弹出一条错误消息,并显示一个对话框,询问我是否要中止、重试或忽略。

它看起来像这样:


Microsoft 可视化C++运行时库

(x( 调试错误!

程序:C\用户\超级\桌面\无效\调试\无效.exe

abort(( 已被调用

(按重试以调试应用程序(


如果我不创建新线程,而只是调用"run(("函数,则程序运行时没有任何调试错误。

这是启动线程的代码

void Application::start()
{
std::thread newThread(&Application::run, this);
while (!running)
{
std::cout << "Not Running!" << std::endl;
}
}

这是应用程序运行的代码

void Application::run()
{
setup();
running = true;
//using namespace std::chrono;
auto lastTime = std::chrono::high_resolution_clock::now();
auto timer = std::chrono::high_resolution_clock::now();
double delta = 0;
int ticks = 0;
while (running)
{
setTargetTPS(60);
auto now = std::chrono::high_resolution_clock::now();
delta += std::chrono::duration_cast<std::chrono::nanoseconds>(now - lastTime).count() / ns;
lastTime = now;
while (delta > 1)
{
update();
ticks++;
delta--;
}
if     (std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - timer).count() > 1000)
{
timer = std::chrono::high_resolution_clock::now();
tps = ticks;
ticks = 0;
std::cout << "TPS: " << tps << std::endl;
}
}
}

游戏是应用程序的子类,我是这样用的

#include "Game.h"
int main()
{
Game* game = new Game();
game->start();
return 0;
}

正如 drescherjm 已经评论的那样,当Application::start完成时(紧接在Application::run更改running之后true,这发生在它开始时(,newThread的析构函数被调用。

根据 Thread::~thread 的 cppreference 页面,当前运行的thread的析构函数调用std::terminate(),根据此调用(默认情况下(std::abort(),导致您看到的消息。

简而言之,你不能让一个正在运行的Thread超出范围。
如果合适,您可以简单地在Application::start中调用newThread.join(),这将保持它直到线程完成。

或者你可以打电话给newThread.detach().这将使newThread从主线程中消失,使其无法join- 这可能是好是坏,这取决于您的需求。在这种状态下,尽管线程本身仍在运行,但newThread变量可能会被和平地破坏(因为分离线程会断开它与保存它的变量的连接(。