【问题标题】:Priority between thread messages?线程消息之间的优先级?
【发布时间】:2011-10-02 10:21:46
【问题描述】:

虽然我在 Borland C++ 应用程序的上下文中引用了这个,但这个问题既是 Borland 特有的,也是通用的。

在 Borland C++ 项目中,我观察到用户与 GUI 的交互(比如单击菜单项)的优先级低于使用 Synchronize() 委托给主线程的任务,即使用户交互发生在几毫秒之前。当主线程可用时,首先完成委托的任务,然后执行与用户交互对应的动作。工作线程将任务委托给主线程并使用 Synchronize() 等待任务完成。所以我们可以将 Synchronize() 等同于 SendMessage()。

我相信用户交互在消息队列中作为消息排队,委托任务也应该如此。但是任务是如何先执行的呢?消息之间是否有任何优先级?

【问题讨论】:

  • 这是对 Borland 实现非常具体的。但消息循环通常会先调度来自同步队列的任何请求,然后继续清空消息队列。
  • @Hans 感谢您的回复。我对问题文本做了一些改动——“当主线程可用时”。不知道这是否重要,但以防万一。

标签: c++ multithreading c++builder


【解决方案1】:

直到并包括 C++Builder 5,Synchronize() 确实调用了SendMessage()。但在 C++Builder 6 中,Synchronize() 被重写为不再使用SendMessage()(以支持 CLX 下的 Linux)。请求现在被放置在一个 FIFO 队列中,并且 VCL 会定期调用CheckSynchronize() 来处理该队列。即使 CLX 早已死去,Synchronize() 仍然使用相同的 FIFO 队列(并且多年来一直在增强)。

除此之外,在使用SendMessage() 的情况下,它确实具有更高的优先级。用户交互是发布到主线程消息队列(又名PostMessage())的消息。尽管SendMessage() 直接进入一个窗口的wndproc,但它不会被调用,直到接收窗口的拥有线程执行消息处理,如果由不同的线程发送(以前是Synchronize() 的情况)。对主线程消息队列的待处理 SendMessage() 请求的优先级高于对同一队列的待发布消息,因为在处理待处理的 SendMessage() 请求之前,还有其他线程/进程被阻塞。

【讨论】:

  • 勒博。谢谢回复。我猜 Synchronize() 的 FIFO 与 GUI 线程的消息队列不同,前者优先于后者? GUI线程也将在空闲时进行消息处理。对吗?
  • 从BCB6开始,FIFO队列和消息队列是分开的,是的。因为Synchronize() 不再使用消息队列进行同步,所以它现在实际上具有较低的优先级。主线程在空闲和收到WM_NULL 消息时调用CheckSynchronize()Synchronize() 向主消息队列发布 WM_NULL 消息以“唤醒”主线程,让它知道需要尽快调用 CheckSynchronize()。这与旧的 SendMessage() 逻辑非常不同(但更便携)。
  • 感谢您的回复。我现在有点困惑。 Synchronize() 现在依赖于发布到消息队列的 WM_NULL 消息,并且用户交互也发布到此消息队列。从运行 Borland 版本 6 的项目中可以看出,Synchronize() 如何获得更高的优先级?
  • 正如我所说,BCB6+ 中的Synchronize() 本身并不依赖于WM_NULL。当消息队列空闲时,也会处理待处理的请求。因此,Synchronize() 队列完全有可能在用户交互消息到达消息队列之前得到处理。
猜你喜欢
  • 2023-04-09
  • 1970-01-01
  • 2015-02-11
  • 2011-06-25
  • 1970-01-01
  • 1970-01-01
  • 2012-05-31
  • 2012-11-17
  • 2016-06-03
相关资源
最近更新 更多