Очистить перед закрытием QCoreApplication - PullRequest
5 голосов
/ 10 июня 2009

У меня есть консоль QCoreApplication, которая имеет таймеры и выполняет сокетную связь, а также использует заблокированный мьютекс.

Когда я закрываю приложение вручную, оно выдает ошибку, сообщающую, что какой-то мьютекс заблокирован и истекло время ожидания. Можно ли как-нибудь очистить консольное приложение, когда пользователь закрывает его?

Ответы [ 3 ]

16 голосов
/ 10 июня 2009

Очистка должна выполняться деструкторами и дочерними родителями.

Сделайте ваш главный объект (главный объект) дочерним по отношению к QApplication, чтобы он был уничтожен всеми своими дочерними объектами до появления QApplication.

Ты уверен, что убил все свои темы? Если это поток с eventloop, обязательно вызовите QThread::quit() для выхода из Eventloop перед вызовом QThread::wait()

Вы также можете использовать пустоту 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();
}
5 голосов
/ 13 января 2012

Оказывается, что закрытие приложения командной строки (проверено на Win7 и VS2010) нажатием кнопки «закрыть» (красная кнопка «x» в строке заголовка) передает сигнал STATUS_CONTROL_C_EXIT приложению. Все темы прерваны с этим кодом.

Нить 'Main Thread' (0x980) вышла с кодом -1073741510 (0xC000013A).

Поток 'QThread' (0x2388) вышел с кодом -1073741510 (0xc000013a).

Это означает, что невозможно перехватить это с помощью сигнала QCoreApplication::aboutToQuit().

Взгляните на winnt.h или ntstatus.h. Это значение, присвоенное явная константа STATUS_CONTROL_C_EXIT. Время выполнения просто выбрав для завершения вашей программы с кодом, чтобы отметить отмену пользователя работа.

1 голос
/ 10 июня 2009

вы можете подключиться к QCoreApplication :: aboutToQuit сигналу и выполнить необходимую очистку там.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...