Pulire prima di chiudere la QCoreApplication
Domanda
Ho un QCoreApplication
console-based che è dotata di timer e fa comunicazione socket e usa i mutex bloccato.
Quando chiudo manualmente l'applicazione, dà un po 'di errore che dice mutex è bloccato ed è scaduta. C'è un modo che io possa fare pulizia in un'applicazione console quando l'utente lo chiude?
Soluzione
Pulizia dovrebbe essere gestita da distruttori e relazione figlio-genitore.
Fai il tuo oggetto master (quello del principale) un bambino di QApplication quindi è distrutto con tutte le sue Childs prima QApplication è.
Sei sicuro di aver ucciso tutti i thread? Se si tratta di un filo con un'eventloop assicurarsi di chiamare QThread::quit()
per uscire dalla eventloop prima di chiamare QThread::wait()
È inoltre possibile utilizzare il QApplication::qAddPostRoutine ( QtCleanUpFunction ptr )
vuoto
per fare un po 'di pulizia speciale.
Per il debug di quei messaggi che è possibile utilizzare QtMsgHandler qInstallMsgHandler ( QtMsgHandler h )
e scrivere il proprio gestore di messaggi per catturare questi avvertimenti. Se è possibile simulare il problema è possibile impostare un punto di interruzione sul messaggio e vedere sullo stack in cui il messaggio proviene.
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();
}
}
Al fine di pulire con destructor e il bambino-genitore nave di relazione si può prendere il segnale di chiusura console e chiamare QCoreApplication::exit()
all'istanza di applicazione.
#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();
}
Altri suggerimenti
Risulta che la chiusura applicazione a riga di comando (controllato su Win7 & VS2010) premendo 'vicino' (tasto x rosso sulla barra del titolo) passa il segnale STATUS_CONTROL_C_EXIT
all'applicazione. Tutti i thread vengono interrotti con questo codice.
Il filo 'Discussione principale' (0x980) è terminato con il codice di -1.073,74151 milioni (0xC000013A).
Il filo 'QThread' (0x2388) ha terminato con codice -1.073,74151 milioni (0xC000013A).
Ciò significa che non v'è alcun modo per intercettare questo con il segnale QCoreApplication::aboutToQuit()
.
Date un'occhiata a winnt.h
o ntstatus.h
. Questo è il valore assegnato al
manifestare costante STATUS_CONTROL_C_EXIT
. Il tempo di esecuzione è solo
la scelta di terminare il programma con il codice da notare all'utente di annullare
operazione.
è possibile connettersi a QCoreApplication :: aboutToQuit segnale e fare il necessario ripulire lì.