我在程序中遇到了这个异常:0x 00007 FFD 187 CF 61 E(ucrtbase.dll)我的项目是C++/MFC,源代码如下。
我确认这段代码在我的另一个项目,这是一个控制台项目。
ReloadWatchdog.h
#pragma once
class ReloadWatchdog
{
public:
static void Reload();
};
ReloadWatchdog.cpp
#include "pch.h"
#include "ReloadWatchdog.h"
#include <thread>
void ReloadWatchdog::Reload()
{
while (true)
{
using namespace std::chrono_literals;
std::this_thread::sleep_for(std::chrono::minutes(4));
try {
call_method();
}
catch (...) {
}
}
}
主要
BOOL CWatchDogPI336Dlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// ↓this occured exception
std::thread th1(ReloadWatchdog::Reload);
return TRUE;
}
1条答案
按热度按时间bfnvny8b1#
C++11的
std::thread
被设计为拥有底层操作系统线程。默认情况下,std::thread
对象需要比操作系统线程更长寿。这种设计是可以理解的,但有一个不幸的后果:只有当
std::thread
的destructor开始执行时,才能观察到在两个生命周期之间没有保持不变式。因为太晚了,无法抛出异常,所以实现调用std::terminate()
。这是正在发生的事情:
根据具体需要,有三种解决方案:
1.在
th1
上调用detach()
,这放宽了生存期要求。std::thread
示例和操作系统线程可以生存任意时间。1.使
th1
成为CWatchDogPI336Dlg
的非静态类成员。这并不能缓解核心问题,而不是推迟它。当~CWatchDogPI336Dlg
完成时,操作系统线程必须运行完成。1.使用C++20的
std::jthread
代替。有趣的区别是它的destructor将等待操作系统线程终止。这是一个阻塞调用,所以它在这里并不立即适用。