消息循环如何使用线程?

时间:2013-01-24 02:51:20

标签: c++ multithreading winapi messages

我有点困惑,想知道我是否被误导了,在另一篇文章中我被告知“新线程只有在你明确制作时才会被创建.C ++程序默认是单线程的。”当我打开我没有在ollydbg中显式创建新线程的程序时,我多次注意到通常有2个线程在运行。我想了解消息循环如何工作而不停止执行,我得到的解释非常不足以解释它是如何工作的。

消息循环是创建新线程还是占用主线程?如果它接受主线程它是否在执行其他所有操作后执行此操作而不管代码顺序如何?如果它不执行此操作但仍占用主线程它是否会生成一个新线程,以便程序可以执行而不是卡在消息循环中?

编辑:通过实验解决了我的大多数问题。消息循环占用主线程和代码之后的任何代码:

while (GetMessage (&messages, NULL, 0, 0))
{
    TranslateMessage(&messages);
    DispatchMessage(&messages);
}
return messages.wParam;

除非执行特殊操作以使其执行,否则将不执行,因为程序卡在消息循环中。在执行的窗口过程中放置​​一个无限循环会导致程序崩溃。我仍然不明白多线程的神秘感,但是在我想要的程度上。

2 个答案:

答案 0 :(得分:8)

也许开始的地方是要意识到“消息循环”不是的东西;它实际上只是一个线程所做的事情。

Windows中的线程通常属于以下两种类别之一:拥有UI的线程和执行后台工作的线程(例如网络操作)。

一个简单的UI应用程序通常只有一个线程,这是一个UI线程。为了使用UI,线程需要等到有一些输入要处理(鼠标点击,键盘输入等),处理输入(例如更新状态并重绘窗口),然后返回等待更多输入。这整个“等待输入,处理它,重复”的行为是消息循环。 (在这个阶段还值得一提的是消息队列:每个线程都有自己的输入队列,用于存储线程的输入消息;线程“等待输入”的行为实际上是关于检查队列中是否有任何内容如果没有,等到有。)在win32中,如果一个主题正在以这种方式主动处理输入,那么它也被称为“抽取消息”。

典型的简单Windows应用程序的主线代码将首先进行基本初始化,创建主窗口,然后执行wait-for-input-and-process-it消息循环。它通常在用户关闭主窗口之前执行此操作,此时线程退出循环,并继续执行之后出现的代码,这通常是清理代码。

Windows应用程序中的常见体系结构是拥有一个主UI线程 - 通常这是主线程 - 它创建并拥有所有UI,并且有一个消息循环,为线程创建的所有UI分派消息。如果应用程序需要执行可能阻塞的操作(例如从套接字读取),则通常会将工作线程用于此目的:您不希望UI线程阻塞(例如,在等待来自套接字的输入时) ,因为它不会在那段时间处理输入,UI最终会没有响应。

你可以编写一个包含多个UI线程的应用程序 - 然后每个创建窗口的线程都需要自己的消息循环 - 但这是一种相当先进的技术,并不是对大多数基本应用程序都有用。

您看到的其他线程可能是某些由Windows创建的辅助线程来执行后台任务;在大多数情况下,你可以忽略它们。例如,如果你初始化COM,那么windows最终可能会创建一个工作线程来管理一些COM内部资源,它也可能会创建一些不可见的HWND。

答案 1 :(得分:2)

通常,启动程序的线程只运行消息循环,占用主线程。任何不属于处理消息或更新UI的内容通常由其他线程完成。即使您的应用程序不创建任何线程,您看到的其他线程也可以由库或操作系统创建。 Windows将在您的流程中创建线程,以处理将事件分派到消息循环中的事情。