2016-12-09 55 views
-4

我想要停止從另一線程主線程,如果捕獲VK_ESCAPE鍵和恢復主線程時,用戶按任意鍵。 我打算建設「ThreadProc1」線程搭上按鍵:如何從c/C++中的另一個線程停止主線程

DWORD WINAPI ThreadProc1(LPVOID param){ 
    while(1){ 
     if(GetAsyncKeyState(VK_ESCAPE)){ 
      //Stop the main thread 
     } 
    } 
} 
+0

主線程無法在不退出程序的情況下停止 – TomJ

+2

您是否想要*殺死*線程,或只是*暫停*它? –

+5

另外,我認爲你的設計有點落後。通常你會產生線程來執行其他工作,而主線程繼續處理主要事件(如檢查鍵盤按下)。 –

回答

1

不要那樣做。或者:1)使主線程在接收到Esc鍵的消息時再跳過所有有意義的動作,直到再次按下。 2)使用CreateEvent並在其上有主線程WaitForMultipleObjects,然後用其他線程的SetEvent喚醒或超時。

主線程如果啓動消息泵,是Windows應用程序的「心臟和大腦」,停止它相當於臨牀死亡。可以返回的「阻塞」動作,比如從文件,套接字等讀取是合法的,指出其他線程不會由於死鎖而導致。睡覺是合法的,因爲線程可以被喚醒。將消息泵線程置於睡眠而不替代消息泵是可疑美德的行爲,這種應用可能被認爲是「掛起」。停止這種方式的驅動程序將被殺死,服務無限期掛起,桌面GUI將提供用戶停止應用程序(或者在企業環境中停止該應用程序,如果管理員偏執狂),並將其標記在任務欄中「無響應」等

+0

Windows應用程序沒有*「主線程」*的概念。有一個*「主線程」*,但這只是您的平均線程,它的唯一特徵是,它是在一個進程中創建的第一個線程。阻塞主線程沒有不利影響(除非該線程擁有GUI)。 'WaitForSingleObject' **會阻塞**,並且從GUI線程調用它是合法的,它將導致掛起的GUI。 [MsgWaitForMultipleObjects](https://msdn.microsoft.com/en-us/library/windows/desktop/ms684242.aspx)是一個更好的選擇(即使使用棘手)。 – IInspectable

+2

當概率大於0.999時,創建的第一個線程是GUI線程 –

+0

@DavidHeffernan:軟件開發不是統計學練習。此外,99.9%的統計數據都是由稀薄的空氣組成的。 – IInspectable

1

正式中止線程是很容易 - SuspendThread然後ResumeThread - 但是:

此功能主要是用來調試程序的使用。它不是旨在用於線程同步的 。在擁有同步對象(如互斥鎖或關鍵部分)的線程上調用SuspendThread 可能會導致死鎖,前提是調用線程嘗試使用 來獲取暫停線程擁有的同步對象。要避免這種情況,應用程序中不是調試器的應用程序中的線程應該指示其他線程自行掛起。目標 線程必須設計爲觀察此信號並適當地響應 。

很有可能的情況 - HeapAllocHeapFree在掛起時由線程調用(並且它在windows消息處理中頻繁地調用)。和線程暫掛堆臨界區。如果在此之後工作線程也直接或間接(此可能性非常高)調用HeapAlloc(或任何其他堆函數爲同一堆 - 通常這是主進程堆) - 您有死鎖。

你當然可以說給主線程發送一些帶有事件句柄的已知消息 - 主線程將等待事件,直到工作線程不調用SetEvent - 但這也不好,並且不是質量解決方案。

UI線程一定不能阻塞等待,在Windows消息上永久等待。我不完全知道你嘗試執行哪個任務,但100%確定存在的解決方案根本不會阻塞UI線程

相關問題