2011-12-19 19 views
8

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

यह अब तक अच्छा काम करता है, हालांकि मुझे इस धागे के निष्पादन को रोकने के लिए एक अच्छा समाधान नहीं मिला है। धागा हमेशा एक उपयोगकर्ता इनपुट के लिए इंतज़ार कर रहा है:

while(appRunning) 
{ 
    std::cin>>theUserCommand; 
    // ...do stuff 
} 

फिर जब चित्रमय आवेदन समाप्त हो जाती है, यह सब सांत्वना कार्यों बंद हो जाएगा, जिसमें मैं धागा शामिल हैं:

appRunning = false; 
// do some more related clean up 
myListeningThread->join(); 

आप देख सकते हैं शामिल होने के बाद, std :: cin उपयोगकर्ता इनपुट के लिए इंतजार कर रहा है। मैंने कोशिश किए गए समाधानों में से एक है "घटनाओं को सिंथेटिज़ करना", std :: cin आपको ENTER के साथ जो भी मूल्य भेजता है, वह धागा अच्छी तरह खत्म हो जाएगा, यह समाधान भयानक है और मैं इसे रखना नहीं चाहता । इसके अलावा, यह उपकरण को निष्पादित वातावरण में से एक में काम करता है, लेकिन जब मैं UI API के साथ इसका उपयोग करने का प्रयास करता हूं तो विफल रहता है। क्या आप लोग मुझे मार्गदर्शन कर सकते हैं कि मैं इसे सही तरीके से कैसे ठीक कर सकता हूं? वास्तव में यह सुनिश्चित करने के लिए नहीं कह सकता कि सी ++ दस्तावेज़ीकरण में std :: cin उपयोगकर्ता इनपुट के लिए प्रतीक्षा करने के लिए एक फ़ंक्शन है, और बस प्रोग्राम निष्पादन जारी रखें, क्या यह भी संभव है?

संपादित करें: ठीक है मुझे लगता है कि keybd_event कुछ वातावरण के लिए थोड़ा भ्रामक है, स्पष्ट रूप से WriteConsoleInput के साथ इनपुट हैंडलर को स्पष्ट रूप से निर्दिष्ट करता है।

+0

कई संभावनाएं हैं, लेकिन वे सभी ओएस-निर्भर हैं। इस कार्यक्रम के लिए कौन सा ऑपरेटिंग सिस्टम है? – zwol

+0

विन/वीस्टूडियो 9.0, मैंने जिस समाधान का उल्लेख किया है, उसके लिए मैंने keybd_event का उपयोग किया है, अगर यह ओएस-निर्भर होगा तो कोई समस्या नहीं है। आप इसे ठीक करने के लिए मुझे कैसे सलाह देंगे? – notNullGothik

+0

बीटीडब्ल्यू, SetConsoleCtrlHandler वास्तव में मेरे लिए काम नहीं करता है, यह एप्लिकेशन प्रक्रिया समाप्त होने के लिए सभी साफ-सफाई को छोड़कर एप्लिकेशन प्रक्रिया समाप्त कर देगा। – notNullGothik

उत्तर

1

मैं विंडोज प्रोग्रामर का अधिकतर नहीं हूं, मुझे यूनिक्स के बारे में बहुत कुछ पता है। और मैं पूरी तरह से boost::thread से अपरिचित हूं। जिसके अनुसार, this MSDN page के तल पर सलाह के आधार पर, यहाँ मेरी सिफारिश है:

  • एक event object बनाएं इससे पहले कि आप कंसोल-पढ़ने धागा पैदा करते हैं।
  • जब आप बंद करना चाहते हैं, तो थ्रेड के ->join विधि को कॉल करने से पहले तुरंत ईवेंट ऑब्जेक्ट पर SetEvent पर कॉल करें।
  • बदलें अपने कंसोल-पढ़ने सूत्र में मुख्य लूप बल्कि istream::operator>> से WaitForMultipleObjects में ब्लॉक करने के लिए, कुछ इस तरह:

    for (;;) { 
        HANDLE h[2]; 
        h[0] = GetStdHandle(STD_INPUT_HANDLE); 
        h[1] = that_event_object_I_mentioned; 
        DWORD which = WaitForMultipleObjects(2, h, FALSE, INFINITE); 
    
        if (which == WAIT_OBJECT_0) 
         processConsoleCommand(); 
        else if (which == WAIT_OBJECT_0 + 1) 
         break; 
        else 
         abort(); 
    } 
    
  • यह धागा किसी भी अवरुद्ध WaitForMultipleObjects कॉल के अलावा अन्य संचालन करने के लिए नहीं ख्याल रखना चाहिए । नीचे दी गई टिप्पणियों में चर्चा के अनुसार, इसका मतलब है कि processConsoleCommandcin का उपयोग नहीं कर सकता है। यह सुनिश्चित करने के लिए कि आप ब्लॉक नहीं करते हैं, आपको low-level console input functions, विशेष रूप से GetNumberOfConsoleInputEvents और ReadConsoleInput का उपयोग करने की आवश्यकता होगी; आपको कैरिज रिटर्न पढ़ने तक processConsoleCommand पर कई कॉलों में वर्ण जमा करने की आवश्यकता होगी; और आपको अपनी खुद की प्रतिध्वनि करने की भी आवश्यकता होगी।

+0

ध्यान दें कि अवरुद्ध पढ़ने से बचने के लिए 'WaitForMultipleObjects()' का उपयोग करके मानक इनपुट पर अवरुद्ध करना मूल रूप से अविश्वसनीय है। यदि मानक इनपुट कुंजीपटल ('CONIN $ 'डिवाइस) है, तो किसी भी कुंजी को दबाकर (यहां तक ​​कि, जैसे कि' CTRL', जो कोई इनपुट नहीं उत्पन्न करता है) केवल अगले इनपुट ऑपरेशन को अनिश्चित काल तक अवरुद्ध करने के लिए प्रतीक्षा को अनवरोधित कर देगा, जिसके परिणामस्वरूप घटना की स्थिति को अनदेखा धागा। अधिक जानकारी के लिए एक [संबंधित प्रश्न] देखें (http://stackoverflow.com/questions/8347642/checking-win32-file-streams-for-available-input)। –

+0

यह वास्तव में कोई फर्क नहीं पड़ता कि यह थ्रेड 'WaitForMultipleObjects' के माध्यम से कताई करता है जब उपयोगकर्ता टाइप कर रहा है, जब तक कि उपयोगकर्ता * टाइप नहीं कर रहा हो, जब तक यह ठीक से निष्क्रिय हो जाता है। मुझे लगता है कि ['FIONREAD'] (http://www.daemon-systems.org/man/ioctl.2.html) के कुछ समकक्ष हैं जिनका उपयोग यह सुनिश्चित करने के लिए किया जा सकता है कि 'रीडफाइल' ब्लॉक नहीं होगा, लेकिन विंडोज़ ने मुझे पहले इसी तरह की सुविधाओं की अनुपस्थिति से आश्चर्यचकित कर दिया है। अगर ऐसा कुछ काम करने के लिए नहीं किया जा सकता है, तो मुझे लगता है कि मैं अपनी खुद की कंसोल विंडो को जीयूआई एपीआई के साथ लागू करने की सोच रहा हूं। – zwol

+0

... उस संबंधित प्रश्न में चर्चा वास्तव में मदद नहीं करता है; अनुशंसा "कंसोल से पढ़ने के लिए समर्पित धागे का उपयोग करें" और यहां हम चर्चा कर रहे हैं कि इस तरह के थ्रेड को कैसे कार्यान्वित किया जाए। – zwol