2009-06-10 4 views
5

बंद करने से पहले साफ़ करें मेरे पास एक कंसोल-आधारित QCoreApplication है जिसमें टाइमर हैं और सॉकेट संचार करता है और लॉक म्यूटेक्स का भी उपयोग करता है।QCoreAplication

जब मैं मैन्युअल रूप से एप्लिकेशन बंद करता हूं, तो यह त्रुटि देता है कि कुछ म्यूटेक्स लॉक हो गया है और यह समय समाप्त हो गया है। क्या कोई तरीका है कि जब मैं इसे बंद करता हूं तो कंसोल एप्लिकेशन में साफ़ कर सकता हूं?

उत्तर

15

क्लीनअप को विनाशकों और बाल-अभिभावक संबंधों द्वारा संभाला जाना चाहिए।

अपने मास्टर ऑब्जेक्ट (मुख्य में से एक) को QApplication के बच्चे बनाएं ताकि QAplication से पहले यह अपने सभी बच्चों के साथ नष्ट हो जाए।

क्या आप वाकई अपने सभी धागे को मार चुके हैं? अगर ऐसा है एक 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(); 
} 
+0

लगभग पूरा हो गया।एक बार जब आप बाहर निकलेंगे (0) आपको अपने क्यूटी विशिष्ट क्लीनअप कोड को कहीं कहीं करना है जो सिग्नल हैंडलर ExitQt() में नहीं है। इसलिए आपको अपने क्यूटी क्लीनअप कोड को टॉक्यूइट() सिग्नल में जोड़ना होगा। qT-> निकास (0) को बुलाए जाने के बाद लगभग टूकुइट सिग्नल केवल उत्सर्जित होता है। –

+2

सी ++ 11 इसे और अधिक आसान बनाता है: 'सिग्नल (SIGTERM, [] (int sig) {qApp-> छोड़ें();}); ' – ManuelSchneid3r

+0

यह पूरी तरह से काम नहीं कर रहा है। मैंने क्लीनअप से संबंधित वस्तु को क्यूप्लिकेशंस का एक बच्चा बना दिया है। खिड़की सामान्य रूप से बंद होने पर विनाशक को ठीक से बुलाया जाता है। लेकिन सिस्टम शट डाउन/लॉगआउट पर, क्यूप्लिकेशन बाल विनाशक को कभी नहीं कहा जाता है। – galinette

1

आप QCoreApplication::aboutToQuit सिग्नल से कनेक्ट कर सकते हैं और वहां आवश्यक आवश्यक सफाई कर सकते हैं।

+2

हाय डैनियल, मैंने कोशिश की, लेकिन ब्रेक प्वाइंट कनेक्ट एसएलओटी में नहीं मारा जाता है। प्रलेखन के बारे में बताता है QCore अनुप्रयोग पर छोड़ने पर टॉक्यूट सिग्नल उत्सर्जित होता है। क्या कंसोल एप्लिकेशन बंद करने से बाहर निकलें()? धन्यवाद, सुरेश। –

5

बाहर कर देता है कि बंद करने कमांड लाइन आवेदन 'बंद करें' दबाने (शीर्षक पट्टी पर लाल x बटन) द्वारा (Win7 & VS2010 पर जाँच) आवेदन करने के लिए STATUS_CONTROL_C_EXIT संकेत गुजरता है। सभी धागे इस कोड के साथ निरस्त कर रहे हैं।

धागा 'मुख्य थ्रेड' (0x980) कोड -+१०७३७४१५१० (0xc000013a) के साथ बाहर निकल गया है।

धागा 'QThread' (0x2388) कोड -1073741510 (0xc000013a) से बाहर निकला है।

इसका मतलब है कि QCoreApplication::aboutToQuit() सिग्नल के साथ इसे रोकने का कोई तरीका नहीं है।

winnt.h या ntstatus.h पर एक नज़र डालें। यह मान मैनिफेस्ट स्थिर STATUS_CONTROL_C_EXIT को असाइन किया गया मान है। रनटाइम सिर्फ उपयोगकर्ता के ऑपरेशन को नोट करने के लिए कोड के साथ अपने प्रोग्राम को समाप्त करने का चयन कर रहा है।

+0

इन्हें रोकने के लिए SetConsoleCtrlHandler() का उपयोग करें, और qApp-> निकास (42) पर कॉल करें – Macke