win32程序应该始终是多线程的吗



现在我正在编写一个win32/opengl应用程序,每个窗口有2个线程。一个线程处理opengl绘图,另一个线程则处理windows消息事件。我的问题是,我应该只对所有窗口消息使用1个线程吗?这会导致诸如窗口偶尔不响应之类的问题吗?

我使用了多个windows消息循环,都在不同的线程上。在我看来,消息循环是为1个线程设计的,并且在一个进程中只出现一次。这是正确的吗?

我应该对所有窗口消息只使用1个线程吗?

你可以,也可以。它不是由操作系统强制执行的,但可能是由GUI框架强制执行的。

这会导致诸如窗口偶尔不响应之类的问题吗?

它本身不会导致该问题。响应不佳的消息循环通常是由于在处理来自操作系统UI驱动程序的消息的窗口的wndprocs/事件处理程序中执行了太多工作,或者实际上在其中等待一些东西,而不是及时返回GetMessage调用。操作系统检测到来自KB等的消息没有得到处理,并倾向于重影窗口,通常会抱怨"没有响应"的应用程序。

如果WMQ用于与不处理UI消息的线程通信,例如消息编号为WM_APP以上的线程,则如果处理此类消息的线程在返回其GetMessage调用之前执行了长时间和/或阻塞操作,则操作系统将不采取任何操作。

在我看来,消息循环是为1个线程设计的一个过程中只有一次出现。这是正确的吗?

不,不是。

Windows消息队列和相关的GetMessage()循环可以并且经常用于在进程的线程之间进行通信。WMQ是专门的生产者-消费者队列,主要用于通信GUI消息。因此,它们对消息格式有限制,并且只有一个线程可以在队列上等待,但WMQ可以用于在非GUI线程之间进行通信。

窗口绑定到创建它们的线程是正确的,并且许多GUI框架的设计/编写方式使得从多个线程使用它们是不安全的,但在一个进程中使用许多windows消息队列和消息处理程序肯定是可能的。

这取决于实现。如果独立进程不应该干扰程序流,那么多线程通常是有意义的。然而,也有其他方法可以实现类似的目标。例如,您可以使用定时器中断流几毫秒,并执行其他线程将要执行的操作。

如果你意识到你的窗口事件线程已经超出了它的极限,比我最初想象的要多,那么你可能不仅在做事件处理,而且在做更多的计算。在那里,开始一个新的线程是有意义的。

编辑:我不是windows专业人士。但我所知道的几乎所有实现都只使用一个线程(循环)作为事件系统。Qt有一些优雅的方法来避免中断,并通过以不同的方式生成新线程来扩展事件系统。它还支持与定时器相结合的信号/插槽。也许你有兴趣使用它。

最新更新