5

我有一个基于控制台的QCoreApplication,它具有计时器并进行套接字通信,并且还使用锁定的互斥锁。

当我手动关闭应用程序时,它会提示某些互斥锁已锁定并且已超时。当用户关闭控制台应用程序时,有什么方法可以在控制台应用程序中进行清理吗?

4

3 回答 3

17

清理应由析构函数和子父关系处理。

使您的主对象(主对象)成为 QApplication 的子对象,以便在 QApplication 之前将其与所有子对象一起销毁。

你确定你杀死了你所有的线程?如果它是带有事件循环的线程,请务必在调用QThread::quit()之前调用以退出事件循环QThread::wait()

您还可以使用 voidQApplication::qAddPostRoutine ( QtCleanUpFunction ptr ) 进行一些特殊的清理。

为了调试这些消息,您可以使用 QtMsgHandler qInstallMsgHandler ( QtMsgHandler h )并编写自己的消息处理程序来捕获这些警告。如果您可以模拟问题,您可以在消息上设置断点并查看消息来自的堆栈。

void debugMessageHandler( QtMsgType type, const char *msg ){
    if(QString(msg).contains( "The message you can see in the console" )){
        int breakPointOnThisLine(0);    
    }

    switch ( type ) {
        case QtDebugMsg:
            fprintf( stderr, "Debug: %s\n", msg );
            break;
        case QtWarningMsg:
            fprintf( stderr, "Warning: %s\n", msg );
            break;
        case QtFatalMsg:
            fprintf( stderr, "Fatal: %s\n", msg );
            abort();
    }
}

为了清理析构函数和子父关系,您可以捕获控制台关闭信号并调用QCoreApplication::exit()应用程序实例。

#include <csignal>
#include <QtCore/QCoreApplication>
using namespace std;

struct CleanExit{
    CleanExit() {
        signal(SIGINT, &CleanExit::exitQt);
        signal(SIGTERM, &CleanExit::exitQt);
        signal(SIGBREAK, &CleanExit::exitQt) ;
    }

    static void exitQt(int sig) {
        QCoreApplication::exit(0);
    }
};


int main(int argc, char *argv[])
{
    CleanExit cleanExit;
    QCoreApplication a(argc, argv);
    return a.exec();
}
于 2009-06-10T13:51:45.477 回答
5

事实证明,通过按“关闭”(标题栏上的红色 x 按钮)关闭命令行应用程序(在 Win7 和 VS2010 上检查)会将STATUS_CONTROL_C_EXIT信号传递给应用程序。所有线程都使用此代码中止。

线程“主线程”(0x980) 已退出,代码为 -1073741510 (0xc000013a)。

线程 'QThread' (0x2388) 已退出,代码为 -1073741510 (0xc000013a)。

这意味着没有办法用QCoreApplication::aboutToQuit()信号拦截它。

看看winnt.hntstatus.h。那是分配给清单常量的值STATUS_CONTROL_C_EXIT。运行时只是选择用代码结束您的程序以记录用户的取消操作。

于 2012-01-13T15:33:58.027 回答
1

您可以连接到QCoreApplication::aboutToQuit信号并在那里进行必要的清理。

于 2009-06-10T13:39:21.120 回答