2011-12-19 92 views
8

在圖形應用程序中,我使用控制檯輸入執行調試命令。當創建控制檯時,還會創建一個新線程來收集處理所有輸入的用戶命令,圖形應用程序將繼續並行運行。我使用boost :: thread庫。可能阻止cin等待輸入嗎?

它迄今爲止效果很好,但是我還沒有找到一個很好的解決方案來停止執行此線程。線程總是等待用戶輸入:

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

然後在圖形應用程序結束時,將停止所有控制檯的功能,其中包括我的主題:

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

正如你所看到的std :: cin將在聯接被調用後等待用戶輸入。 我試過的一個解決方案是創建事件「合成擊鍵」,std :: cin將得到你用ENTER發送的任何值,線程將很好地結束,這個解決方案是可怕的,我不想保留它。 此外,它在該工具執行的環境之一中工作,但當我嘗試使用它與UI API一起使用時失敗。你們能指導我如何以正確的方式解決這個問題?不能確切地說,如果在C++文檔中有一個函數阻止std :: cin等待用戶輸入,並且只是繼續執行程序,它甚至有可能嗎?

編輯:很好,我發現keybd_event對於某些環境有點誤導,用WriteConsoleInput顯式指定輸入處理程序的效果很好。

+0

有幾種可能性,但它們都依賴於操作系統。這個程序的操作系統是什麼? – zwol 2011-12-19 23:42:27

+0

Win/VStudio9.0,我用我提到的解決方案的keybd_event,如果它依賴於操作系統是沒有問題的。你會如何推薦我解決它? – notNullGothik 2011-12-20 00:13:50

+0

順便說一句,SetConsoleCtrlHandler並不適合我,這將結束應用程序進程跳過應用程序的所有清理結束。 – notNullGothik 2011-12-20 00:21:16

回答

1

我不是一個Windows程序員,我知道更多關於Unix的知識。我完全不熟悉boost::thread。也就是說,基於在this MSDN page底部的意見,這是我的建議:

  • 創建event object創建控制檯讀取線程之前。
  • 當您想要關閉時,請在調用線程的->join方法之前立即在事件對象上調用SetEvent
  • 變化在控制檯讀取線程的主循環中WaitForMultipleObjects阻止而不是istream::operator>>,這樣的事情:

    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通話以外的任何阻塞操作。根據以下評論中的討論,這意味着processConsoleCommand完全不能使用cin。您將需要使用low-level console input functions代替,特別是GetNumberOfConsoleInputEventsReadConsoleInput,以確保您不會阻止;您需要在processConsoleCommand多次調用之前積累字符,直到您閱讀回車;你也需要做你自己的迴應。

+0

請注意,使用'WaitForMultipleObjects()'阻止標準輸入以避免阻塞讀取從根本上是不可靠的。如果標準輸入是鍵盤('CONIN $'設備),那麼按下任何鍵(即使是那些不產生輸入的「CTRL」鍵)都將解除阻塞等待,無限期地阻止下一個輸入操作,從而導致該線程忽略事件的狀態。查看[相關問題](http://stackoverflow.com/questions/8347642/checking-win32-file-streams-for-available-input)瞭解更多詳情。 – 2011-12-20 20:38:34

+0

當用戶輸入時,這個線程是否通過'WaitForMultipleObjects'旋轉並不重要,只要當用戶*不是*鍵入時它正常閒置。我想認爲有一些等同的['FIONREAD'](http://www.daemon-systems.org/man/ioctl.2.html)可以用來確保'ReadFile'不會被阻塞,但之前Windows沒有類似的設施讓我感到意外。如果這樣的事情不能發揮作用,我想我會考慮用GUI API實現我自己的控制檯窗口。 – zwol 2011-12-21 00:02:34

+0

......這個相關問題的討論並沒有真正幫助;該建議似乎是「使用專用線程從控制檯讀取」,這裏我們正在討論如何精確地實現這樣一個線程。 – zwol 2011-12-21 00:03:41