gpt4 book ai didi

C++ CTRL+C 处理程序具有未定义的行为?

转载 作者:行者123 更新时间:2023-11-28 04:04:45 24 4
gpt4 key购买 nike

我有一个在 Windows 10 上运行的大型 C++ 程序,它有一个主系统响应套接字请求和 2 个线程通过套接字客户端类的单独实例运行监控系统。

在软件关闭时(CTRL+C 或退出 X 按钮),我需要能够优雅地停止 2 个线程,线程通过套接字关闭一些物理设备。

注册 CTRL+C 事件时,将调用 sExit() 函数。此函数设置原子变量 kill_child_threads=true 以终止远程线程中的 while 循环。不幸的是,当我加入远程线程时,它们似乎并没有加入,或者至少加入没有阻止 sExit() 函数。

然后 sExit() 函数随机“退出?”,没有完成所有代码。但是程序似乎根据窗口和退出代码干净地关闭了。 VS2019 未检测到任何问题,程序以 0xc000013a (Windows CTRL+C) 退出。

当我尝试调试进入 sExit() 函数时,它会运行几行,但在某些时候它“崩溃”或只是退出整个程序而没有任何异常或完成功能。它不会每次都发生在同一条线上,而是发生在不同的点。它有时会在调用 thread.join() 之前或之后“崩溃”,并且根据日志记录,程序经常在 2 个子线程完成之前崩溃。

下面的配置过去使用 1 个线程,但最近添加了第二个线程后,我得到了我认为未定义的行为。

任何帮助或调试方法都会非常有帮助。
请注意 LOG 系统是线程安全的。

在 main.cpp 顶部定义并在 main(void) 中创建线程:

//top of main.cpp
std::thread *rotor_thread;
std::thread *heat_thread;

//main()
rotor_thread= new std::thread(TubeControl::rotorThing);
heat_thread= new std::thread(HeatExControl::heatThing);
BOOL WINAPI sExit(DWORD CtrlType)
{

if ((CtrlType == CTRL_CLOSE_EVENT) | (CtrlType == CTRL_C_EVENT)) {
LOG(DEBUG) << "Entering Close Event or Ctrl-C Event";

//Kill Tube rotor thread & spin to ECO mode.
kill_child_threads.store(true, std::memory_order_seq_cst);
try
{
heat_thread->join();
rotor_thread->join();
}
catch (std::exception & e)
{
LOG(ERROR) << "Issue Killing:" << e.what();
}
//More stuff here on main thread...
//That never executes, or sometimes partially executes.
}

线程 1:

void rotorThing(void)
{
while (!kill_child_threads.load(std::memory_order_seq_cst))
{
//Do Thread safe stuff.
//Sleep
std::this_thread::sleep_for(std::chrono::seconds(1));
}
//Program shutting down
try
{
LOG(INFO) << "[Rotor] xxxxxxxxxxxxxxx.";
//Do Thread safe stuff.
}
catch (std::exception & e)
{
LOG(ERROR) << "Issue shutting down tube" << e.what();

}
}

线程 2:

void heatThing(void)
{
enum HEAT_STATE { COLD, HOT };
HEAT_STATE heat_state = HEAT_STATE::COLD;
LOG(DEBUG) << "[Heat] Starting Heat Exchanger Monitoring Thread.";
std::string resp = "";

while (!kill_child_threads.load(std::memory_order_seq_cst))
{
//Check tube speed, and Hx temps and flows
hwHxSock->sendCmd("hx,get_inlet_temp");
float itemp = stof(hwHxSock->getRespString());
LOG(DEBUG) << "[Heat Xfer Mon] xxxxxxxxx";
std::this_thread::sleep_for(std::chrono::seconds(5));
}

hwHxSock->sendCmd("hx,get_inlet_temp");
float itemp = stof(hwHxSock->getRespString());
}

最佳答案

当用户在控制台窗口上单击关闭时 - HandlerRoutine回调(在您的情况下为 sExit)接收 CTRL_CLOSE_EVENT。对于此事件 - 系统在 SPI_GETHUNGAPPTIMEOUT 之后强制终止您的进程(默认为 5000 毫秒)。无论您在您的流程中做什么(情况 - 任何) - 超时后 - 如果您自己不退出 - 您的流程将在外部终止,代码为 STATUS_CONTROL_C_EXIT。这恰好会产生“在随机位置退出”的效果(实际上,您的代码在调用终止时可以在任何地方)

但如果CTRL_C, CTRL_BREAK - 没有超时 - 寻找Timeouts最后一节

关于C++ CTRL+C 处理程序具有未定义的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58944326/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com