现在我正在编写一个win32 / opengl应用程序,每个窗口有2个线程。一个线程处理opengl绘图,另一个处理windows消息事件。我的问题是,我应该只为所有Windows消息使用1个线程吗?这是否会导致窗口无法偶尔响应等问题?
我使用多个Windows消息循环,所有这些都在不同的线程上。在我看来,消息循环是为1个线程设计的,并且在进程中只有一个外观。这是对的吗?
答案 0 :(得分:5)
我应该只为所有Windows消息使用1个线程吗?
你可以,或者不。它不是由操作系统强制执行的,但可能是您的GUI框架。
这是否会导致Windows无法偶尔响应等问题?
它本身不会导致这个问题。响应不良的消息循环通常是由于在wndprocs / event-handlers中执行太多工作导致处理来自OS UI驱动程序的消息的窗口,或实际上在等待它们而不是及时返回到GetMessage调用。操作系统检测到来自KB等的消息未得到处理,并且往往会使窗口重影并且通常会抱怨“无响应”应用程序。
如果WMQ用于与不处理UI消息的线程进行通信,例如,消息号为WM_APP的线程,则如果处理此类消息的线程在获取之前执行冗长和/或阻塞操作,操作系统将不采取任何操作回到它的GetMessage调用。
在我看来,消息循环是为1个线程而设计的 一个过程中只有一个出现。这是对的吗?
不,不是。
Windows消息队列和关联的GetMessage()循环可以并且通常用于在进程的线程之间进行通信。 WMQ是专门的生产者 - 消费者队列,主要用于传递GUI消息。因此,它们对消息格式有约束,并且只有一个线程可以在队列上等待,但WMQ可用于在非GUI线程之间进行通信。
将窗口绑定到创建它们的线程是正确的,并且许多GUI framewok的设计/编写方式使得从多个线程使用它们是不安全的,但许多Windows消息队列和消息 - 一个过程中的处理程序当然是可能的。
答案 1 :(得分:1)
这取决于实现。如果独立进程不应该干扰程序流,多线程通常会有意义。然而,还有其他方法可以实现类似的事情。例如。您可以使用计时器将流量中断几毫秒并执行其他线程将执行的操作。
如果您认识到您的窗口事件线程正在达到它的极限,那么我认为您可能不会仅进行事件处理,而是进行更大的计算。在那里开始一个新线程是有意义的。
编辑:我不是Windows专业版。但我知道的几乎所有实现都只为事件系统使用一个线程(循环)。 Qt有一些优雅的方法来规避中断并通过以不同方式生成新线程来扩展事件系统。它还支持信号/插槽与定时器的组合。也许你有兴趣使用它。