免责声明:在多线程方面,我有点菜鸟。我在网上阅读了一些东西,做了一些简单的多线程示例。
我有一个 Win32 应用程序,它想在一个线程中绘制内容并在另一个线程中处理 Win32 消息。但是,在创建窗口并启动线程后,它会挂起。我有一种预感,它可能与WaitForMultipleObjects()有关,但我不知道如何使它正确。有谁知道为什么会这样?我应该暂停和恢复线程吗?
这是我的代码:
WinAPI:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int nCmdShow)
{
/* initialization blah blah */
zgE->startThreads(); // <--- starts the 2 threads
WaitForMultipleObjects(zgE->getThreadsNo(), zgE->getThreads(), TRUE, INFINITE);
return TRUE;
}
这就是我启动线程的方式:
void zgEngine::startThreads()
{
/* allocation and stuff, blah blah blah */
m_arrThreads[m_nThreads++] = CreateThread(NULL, 0, &zgEngine::handleMsg, (void*)this, NULL, NULL);
m_arrThreads[m_nThreads++] = CreateThread(NULL, 0, &zgEngine::drawObjects, (void*)this, NULL, NULL);
assert(m_nThreads <= THREADS_NO);
}
绘制和处理消息的 2 个函数非常简单。它们每个都有一个while循环。
// draw function
DWORD WINAPI zgEngine::drawObjects(LPVOID lpParam)
{
while (true)
{
/* draw stuff - valid code that if called outside this function
works as intended */
}
return TRUE;
}
// message handler function
DWORD WINAPI zgEngine::handleMsg(LPVOID lpParam)
{
MSG msg;
while (true)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
// Process the message
if (msg.message == WM_QUIT)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return TRUE;
}
当我不使用线程并删除drawObjects()中的“while(true)”,但留下代码(只执行一次)时,不要调用handleMsg()并像下面的例子一样制作WinMain,它奇迹般有效。
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int nCmdShow)
{
/* initialization blah blah */
MSG msg;
while (true)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
// Process the message
if (msg.message == WM_QUIT)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
} else {
zgEngine::DrawObjects(zgE);
}
}
return TRUE;
}
稍后编辑:据我所见, PeekMessage() 总是返回 0 :(