2011-11-13 67 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。