我有一个基于控制台的QCoreApplication
,它有定时器并进行套接字通信,并且还使用锁定的互斥锁。
当我手动关闭应用程序时,它会错误地说某些互斥锁被锁定并且超时。当用户关闭它时,我有什么方法可以在控制台应用程序中清理它?
答案 0 :(得分:16)
清理应该由析构函数和子父关系来处理。
使您的主对象(主要对象)成为QApplication的子对象,以便在QApplication之前对其所有子对象进行破坏。
你确定你杀了所有的线程吗?如果它是带有eventloop的主题,请务必在致电QThread::quit()
QThread::wait()
退出eventloop
你也可以使用void QApplication::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();
}
答案 1 :(得分:5)
通过按“关闭”(标题栏上的红色x按钮)关闭命令行应用程序(在Win7和VS2010上检查)将STATUS_CONTROL_C_EXIT
信号传递给应用程序。使用此代码中止所有线程。
线程'Main Thread'(0x980)已退出,代码为-1073741510 (0xc000013a)。
线程'QThread'(0x2388)已退出代码 -1073741510(0xc000013a)。
这意味着无法用QCoreApplication::aboutToQuit()
信号拦截此信息。
查看winnt.h
或ntstatus.h
。这是分配给的值
显示常数STATUS_CONTROL_C_EXIT
。运行时只是
选择使用代码结束您的程序以记录用户的取消
操作
答案 2 :(得分:1)
您可以连接到QCoreApplication::aboutToQuit信号并在那里进行必要的清理。