【问题标题】:C++ message passing like Windows's ::SendMessage / ::PostMessageC++ 消息传递,如 Windows 的 ::SendMessage / ::PostMessage
【发布时间】:2015-11-20 15:24:58
【问题描述】:

我正在重构一个程序,以减少它对 Windows 特定结构的依赖。线程模型是“传统的”Windows GUI 模型:有一个“主”GUI 线程,它只执行非常短的操作,以保持 GUI 响应;所有较长的任务都在“工作”线程中完成。所有工作线程仅与 gui 线程通信,它们通过 ::SendMessage 和 ::PostMessage 进行通信(对于不熟悉 Windows API 的人来说,SendMessage 是阻塞的,而 PostMessage 不是)。 'Notification' 样式消息,'like hey I'm done processing',或所有参数都可以适合 2 个 32 位值(发送/PostMessage 的参数)的消息使用 PostMessage 发送,因为没有数据访问需要同步的;必须传递大量数据的消息使用 SendMessage,然后 gui 线程(快速)在它进行“真正”处理(或将“真正”处理传递给另一个工作线程)之前复制它需要的所有内容。这样,永远不会同时访问相同的数据。它有一些限制,但到目前为止它对我们有用;主要优点是它是一个如此简单的模型,您几乎不必认真考虑可能发生的事情或进行显式同步,因为永远不会共享数据访问权限。

我想解除的“唯一”限制是该模型仅用于单向通信:它是从工作人员到 gui 线程。到目前为止,它已经为我们的目的工作了,但我想转移到一个模型,其中所有线程都是平等的,任何线程都可以双向“发布”消息到任何其他线程;然后最重要的是,我想构建一些东西来检查“工作线程”是否只与“主线程”通信,反之亦然;并且永远不要在彼此之间使用“工作线程”。这样,我们将来可以灵活地在线程确实需要 n:n 通信的其他用例中重用该机制。

所以现在我的问题是:如何使用 c++11 或 boost 线程库来复制这种行为?理想情况下,我会有一个全局函数或单例的成员,它可以从任何线程调用,第一个参数是要“调用”的某种线程的 id,也许是某种“消息 id”(消息必须先注册,就像 win32 中的 RegisterUserMessage() 和特定于消息的 void* 一样。接收者将负责投射和解释消息。然后以某种方式在“接收”线程的上下文中调用消息处理方法。

所以我想可能是其他类派生的基类“ThreadBase”; 'ThreadBase' 将提供一个纯虚函数 'HandleMessage(unsigned int msg_id, void* data)' 左右。也许这个'ThreadBase'本身会派生自std::thread?或者有一个 std::thread 成员?然后在(对于这个例子) main() 我会做:

ThreadManager::RegisterMessage(1234);  // 'Thread1 is done'
Thread1 t1(1); // Thread1 and Thread2 both derived from 'ThreadBase'
Thread2 t2(2); // Construction of t1 and t2 would immediately start the thread; alternatively they could have a Run() member?

然后我可以在 t1 的任何地方做:

MyData data;
ThreadManager::SendMessage(2, 1234, (void*)&data);

这将使用参数“1234”和“&data”调用 Thread2::HandleMessage()。

我希望我在这里说得通——我认为从我的问题的措辞中可以清楚地看出我对 win32 API 之外的多线程不是很熟悉。这个想法甚至有意义吗?我忽略的缺点?这如何使用线程原语来实现?谢谢。

【问题讨论】:

    标签: c++ multithreading


    【解决方案1】:

    嗯。您的问题显然不符合 SO 问题格式;),但我不会让您这样做。

    我将尝试解释一些有关 C++ 中的线程模型的内容。首先要记住的是它实际上是在 Posix 线程上建模的。所以你可以在那里找到 Posix 的东西,但不是特定于 Windows 的东西。特别是,这意味着它缺乏对消息传递的任何内置支持。您可以拥有的关闭是一个条件变量,但您只能等待单个条件变量,并且不能多路复用。要使用消息传递,您需要实现自己的消息队列,或者使用第三方库(boost 肯定有一个,以及一堆其他库)。

    【讨论】:

      猜你喜欢
      • 2021-09-04
      • 1970-01-01
      • 1970-01-01
      • 2023-04-07
      • 2012-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多