2011-11-13 101 views
1

使用C和Win32時,我遇到了一個問題,當我的程序凍結而不是在發佈退出消息時關閉(例如Alt-F4),並且必須使用任務管理器結束該過程。如何正確退出我的程序?

我有這個在我的主循環:(問題解決)

MSG msg; 
while(1) 
{ 
    while(PeekMessage(&msg, hwnd, 0, 0, PM_REMOVE)) 
    { 
     if(msg.message == WM_QUIT) 
     { 
      terminate = 1; 
      while(terminate != 3) //each thread increments "terminate" by 1 before returning 
      { 
       Sleep(1); 
      } 
      return 0; 
     } 
     DispatchMessage(&msg); 
    } 
    Sleep(1); 
} 

這將打印 「OK!」在控制檯中,然後凍結。我認爲這可能是因爲我有多個線程,他們沒有正確終止(但我讀過,如果我從我的main()函數返回其他線程應該自動終止)。如果它有助於其中一個線程是OpenGL渲染線程。

+0

除了別人發佈的其他觀點,爲什麼PeekMessage()循環? GetMessage()有什麼問題?這不是我第一次看到這個 - 爲什麼開發人員不斷在CPU循環中浪費內核?除了浪費之外,CPU循環會影響低優先級線程的運行,對於循環數等於或大於內核數的系統來說,這一點非常重要 - 線程可能不會終止的另一個原因(儘管可能不會與退出())有關的問題。 –

+0

我使用PeekMessage循環,因爲這是Code :: Blocks OpenGL項目中使用的。你能否澄清一下PeekMessage和GetMessage的區別? msdn文檔不是很清楚: 「與GetMessage不同,PeekMessage函數不會在返回之前等待消息發佈。」 也是所有主線程所做的是檢查Windows消息(我編輯了問題中的代碼,你是說這是錯誤的?) – Jonathan

+0

差異基本上就像陳述 - GetMesssage()塊,等待消息。當GetMessage正在等待時,因此不使用CPU。 PeekMessage()不會阻塞,所以在等待時,循環會燒燬一個完整的CPU內核。實現你所需要的最有效的方式是擺脫PM和sleep()循環,讓你的終結線程發佈一個WM_APP消息,你可以捕獲並做你從'3倒計時'。如果'代碼::塊OpenGL'suggest PeekMessage和睡眠循環,他們是錯誤..'不是很好' –

回答

1

main功能只是一個線程,你只是終止一個。但是,要結束進程,所有線程都需要正確終止,否則它將永遠運行。一旦收到WM_QUIT消息,您需要保留線索的引用並終止它們。

+0

事實上''main'內'exit'和'return'的行爲是編譯器,甚至是編譯器版本*都依賴於C,因爲C沒有線程的概念。我很確定在VC++中他們最近改變了這種行爲。 –

+0

發現它:http://blogs.msdn.com/b/oldnewthing/archive/2010/08/27/10054832.aspx –

+0

我得到它的工作,確保所有其他線程結束(我認爲退出(0) ;會照顧終止所有線程) – Jonathan

0

退出是退出整個過程。當您致電退出時,您的過程會清理乾淨,例如調用在atexit中註冊的函數,或者在C++的情況下調用全局對象的析構函數。怎麼樣abort()或者terminateProcess。