Вопрос

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

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

Это было полезно?

Решение

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

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

Вы уверены, что убили все свои темы?Если это поток с циклом событий, обязательно позвоните QThread::quit() выйти из цикла событий перед вызовом 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();
}

Другие советы

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

Поток «основной поток» (0x980) вышел с кодом -1073741510 (0xc000013a).

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top