关于消息循环的问题

时间:2010-11-11 06:40:44

标签: windows multithreading operating-system

我有一个困扰我很久的问题。

简短版本:

Windows Message Loop的工作范例是什么?

详细版本:

当我们启动Windows应用程序(不是控制台应用程序)时,我们可以通过鼠标或键盘与它进行交互。应用程序从其meesage队列中检索表示我们的移动的所有类型的消息。 Windows负责收集我们的操作并将消息正确地送入此队列。但这种情况是否意味着Windows必须无限期

我认为 Windows计划程序 应该一直在运行。它可能由预定义间隔的时间中断调用。当调度程序被时间中断触发时,它会切换当前线程以用于下一个挂起的线程。单个线程只能在计划运行时使用GetMessage()获取其消息。

我想知道是否只有一个Windows应用程序正在运行,这个应用程序是否会有更多机会获取其消息?

更新 - 1(2010年11月22日上午9:59)

以下是我的最新发现:

根据< Windows via C / C ++ 5th Edition>第7章部分:线程优先级

  

...例如,如果您的流程'   主线程调用GetMessage()和   系统发现没有消息   等待,系统暂停您的   porcess'线程,放弃了   线程时间片的剩余部分,   并立即分配CPU   另一个等待的线程。

     

如果没有消息显示GetMessage   检索,过程'主要   线程保持暂停状态,永远不会   分配给CPU。但是,当一个   消息放在线程中   队列,系统知道了   线程不应再被暂停   如果没有,则将线程分配给CPU   优先级较高的线程需要   执行。

我目前的理解是:

为了让系统知道消息何时放在线程的队列中,我可以想到两种可能的方法:

1 - 集中式方法:系统负责始终检查每个线程的队列。即使该线程因缺少消息而被阻止。如果有任何消息可用,系统会将该线程的状态更改为可调度。但在我看来,这种检查对系统来说可能是一个“强烈的”负担。

2 - 分布式方法:系统不检查每个线程的队列。当一个线程调用GetMessage并发现没有消息可用时,系统只会将线程的状态更改为阻塞,因此不再可调度。并且将来无论是谁将消息放入阻塞线程的队列中,都是“”(不是系统)负责从阻止 to ready (或任何状态)。 因此,此线程不符合系统的日程安排,并且在GetMessage 方面由其他人重新限定。系统关心的只是安排可运行的线程。系统不关心这些可调度线程的来源。这种方法将避免方法1中的负担,从而避免可能的瓶颈。

事实上,这里的关键点是,线程的状态如何变化?我不确定它是否真的是一个分布式范例,如appraoch 2所示,但它可能是一个不错的选择吗?

3 个答案:

答案 0 :(得分:2)

应用程序在其消息循环中调用GetMessage()。如果消息队列为空,则该过程将阻塞,直到另一条消息可用。因此,GetMessage是告诉Windows目前无需做任何事情的进程方式。

答案 1 :(得分:1)

  

我想知道是否只有一个   Windows应用程序正在运行,会这样   应用程序有更多机会获得它   消息?

好吧,是的,但我认为你可能会错过一个关键点。从队列中提取消息是阻塞调用。使用的数据结构通常称为阻塞队列。 dequeue操作旨在在队列为空时自动生成当前线程的执行。线程可以使用各种不同的方法保持驻留,但在这种情况下,线程很可能使用内核级机制保持等待状态。一旦给出该队列具有可用项目的信号,该线程就可以进入就绪状态,并且调度程序将开始分配其CPU的公平份额。换句话说,如果该应用程序没有待处理的消息,那么它就处于空闲状态,消耗的CPU时间接近零。

答案 2 :(得分:0)

您运行的线程越少(时间片被调度到线程,而不是进程),任何单个应用程序从队列中提取消息的可能性就越大。实际上,这与Windows消息无关;所有多线程都是如此;正在运行的相同或更高优先级的线程越多,任何线程获得的时间片越少。

除此之外,我不确定你在问什么,不过......