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

我有一个在Windows 10上运行的大型C ++程序,该程序具有一个主系统来回答套接字请求,并且有2个线程通过套接字客户端类的单独实例运行监视系统。

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

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

然后,sExit()函数会随机“退出?”,而无需完成所有代码。但是该程序似乎根据Windows和退出代码完全关闭了。 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());
}

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

当用户在控制台窗口上单击关闭时-HandlerRoutine回调(在您的情况下为sExit)将收到CTRL_CLOSE_EVENT。发生此事件-系统强制SPI_GETHUNGAPPTIMEOUT后终止您的进程(默认为5000ms)。在过程中进行的任何操作(情况-任何)-超时后-如果您不退出自己的程序-您的过程将在外部用STATUS_CONTROL_C_EXIT代码终止。这完全可以实现“在随机位置退出”的效果(实际上,在终止调用时,您的代码可以在任何位置)

但如果情况为CTRL_C,CTRL_BREAK-没有超时-最后查找Timeouts部分

本文链接:https://www.f2er.com/3069695.html

大家都在问