私はコンソールベースのQCoreApplication
にタイマを持ち、ソケット通信を行いロックされたミューテックスを使用しています。QCoreApplicationを閉じる前にクリーンアップ
私は手動でアプリケーションを閉じると、それはいくつかのミューテックスがロックされ、それがタイムアウトしていると言ってエラーになります。ユーザーがコンソールアプリケーションを閉じるときに、コンソールアプリケーションでクリーンアップできる方法はありますか?
私はコンソールベースのQCoreApplication
にタイマを持ち、ソケット通信を行いロックされたミューテックスを使用しています。QCoreApplicationを閉じる前にクリーンアップ
私は手動でアプリケーションを閉じると、それはいくつかのミューテックスがロックされ、それがタイムアウトしていると言ってエラーになります。ユーザーがコンソールアプリケーションを閉じるときに、コンソールアプリケーションでクリーンアップできる方法はありますか?
クリーンアップは、デストラクタと子と親の関係で処理する必要があります。
はQApplicationがある前に、それはすべてのチャイルズで破壊されるように、あなたのマスターオブジェクト(メインの1)はQApplicationの子を作成します。
スレッドをすべて削除してもよろしいですか?もしそうであればイベントループでスレッドを使用すると、あなたはまた、いくつかの特別なクリーンアップを行うには、ボイドQApplication::qAddPostRoutine (QtCleanUpFunction ptr)
を使用することができますQThread::wait()
を呼び出す前に、イベントループを終了するQThread::quit()
を呼び出してください。
それらのメッセージをデバッグするために、あなたは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();
}
あなたはQCoreApplication::aboutToQuit信号に接続し、そこに必要なクリーンアップを行うことができます。
こんにちはダニエル、 私はこれを試してみましたが、ブレークポイントは、接続されたスロットにヒットしません。 QCoreApplicationで終了すると、aboutToQuitシグナルが出力されます。コンソールアプリケーションを閉じるとquit()が呼び出されますか? ありがとう、 Suresh。 –
は、「閉じる」(タイトルバーの赤いXボタン)を押して(win7の& VS2010で確認)を閉じるコマンドラインアプリケーションは、アプリケーションにSTATUS_CONTROL_C_EXIT
信号を通過させることが判明しました。すべてのスレッドはこのコードで中止されます。
スレッドのメインスレッド '(0x980)は、コード-1073741510 (0xc000013a)で終了しました。
スレッド 'QThread'(0x2388)がコード -1073741510(0xc000013a)で終了しました。
これは、QCoreApplication::aboutToQuit()
信号でこれを傍受する方法がないことを意味します。
はwinnt.h
またはntstatus.h
を見てみましょう。これは マニフェスト定数STATUS_CONTROL_C_EXIT
に割り当てられた値です。ランタイムは、 のコードをプログラムで終了することを選択して、ユーザーのキャンセル の操作を記録します。
SetConsoleCtrlHandler()を使用してこれらをインターセプトし、qApp-> exit(42)を呼び出して、 – Macke
がほぼ完成しました。exit(0)を呼び出すと、Qt固有のクリーンアップコードをシグナルハンドラexitQt()にないどこかで実行する必要があります。あなたのQtクリーンアップコードをaboutToQuit()シグナルに結びつけなければなりません。 aboutToQuitシグナルは、qApp-> exit(0)が呼び出されたときにだけ発行されます。 –
C++ 11はより簡単になります: 'signal(SIGTERM、[](int sig){qApp-> quit();});' – ManuelSchneid3r
これは完全には機能しません。クリーンアップ関連のオブジェクトをQApplicationの子にしました。デストラクタは、ウィンドウが正常に閉じられたときに適切に呼び出されます。しかし、システムのシャットダウン/ログアウト時には、QApplicationの子デストラクタは決して呼び出されません。 – galinette