C++消息传递:Windows::sEndoMe/::

C++消息传递:Windows::sEndoMe/::,c++,multithreading,C++,Multithreading,我正在重构一个程序,使它更少地依赖于Windows特定的结构。线程模型是“传统”的Windows GUI模型:有一个“主”GUI线程只执行非常短的操作,以保持GUI的响应性;所有更长的任务都在“辅助”线程中完成。所有工作线程仅与gui线程通信,对于不熟悉Windows API的线程,它们通过::SendMessage和::PostMessage进行通信SendMessage是阻塞的,PostMessage不是通知“样式消息”,如“hey I'm done processing”,或所有参数都可以

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

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

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

所以我想可能是一个基类“ThreadBase”,其他类都是从它派生的;'ThreadBase'将提供纯虚拟函数'HandleMessageunsigned int msg_id,void*data'等等。也许这个“线程库”本身就是从std::thread派生出来的?或者有一个std::线程成员?在本例中,我会:

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之外,我对多线程不是很熟悉。这个想法有意义吗?我忽略的缺点?如何使用线程原语实现这一点?谢谢。

Hm.您的问题显然不符合SO问题的格式;,但我不会让你这么做的

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