我的情况是我有一个Emitter对象和一组Receiver。接收器属于同一类,实际上代表一组相同类型的设备。我正在使用Qt框架。
发射器本身首先会收到一个信号,要求其中一个设备提供信息。
在相应的插槽中,发射器必须检查哪个接收器已准备就绪,然后发送自己的信号以向其中一个设备请求数据(以准备好的为准)第一)。
发射器非常快速地接收信号,大约为毫秒。我可以通过三种方式安全地从其中一个设备请求数据(这些设备存在于自己的线程中,所以我需要一个线程安全的机制)。设备数量不是静态的,可以改变。设备总数非常小(绝对低于5-6)。
1)添加或删除设备时连接所有设备。发出一个请求并让设备对象自己过滤掉请求是否是使用某些特定设备标记的请求。这种方法很好,因为检查发生的请求槽将在专用线程的上下文中执行,但随着设备数量的增加而浪费。
2)在发送请求时,请立即与发射器内的物体连接和断开。
3)在发送请求时使用QMetaObject :: invokeMethod()。
表现很重要。有谁知道哪种方法最好?或者哪种方法更好?
此致
的PRI
注意:澄清:发射器从应用程序获取信号,通过查询设备获取信息。疯狂的ASCII艺术去:
(app)< ---->(发射器)< ------>(接收器)< - | - >物理设备
答案 0 :(得分:0)
根据您提供的信息,我仍然建议Reactor
实施。如果您不使用ACE,那么您可以实现自己的。基本架构如下:
select
在从应用程序收到信号或数据时唤醒。Receiver
将自己从可用的套接字/处理程序集中移除Reciever
会将自身重新注册到可用收件人列表。我建议ACE
的原因是因为它具有最简单的Reactor
模式实现之一。
答案 1 :(得分:0)
我在这里很有趣这是多线程环境。
如果你被限制在Qt信号/插槽系统之间那么你的具体问题的答案是:
1)绝对不是要走的路。在Emitter
的发出中,等于Receivers
的事件的总数将排队等待设备的线程事件循环,那么相同数量的槽调用将发生一次线程到达那些事件。即使大部分失去了if(id!=m_id) return;
在他们的第一行,它在Qt的核心中发生了大量的事情。在一个由Qt::QueuedConnection
信号引发的插槽中放置一个断点,并验证这一点,查看实际的堆栈跟踪。它通常至少有4个来自xyEventLoop::processEvents(...)
的深度调用,因此“正在返回”在时间上绝对不是“免费”。
2)不确定Qt的内部实现是如何实现的,但据我所知,连接和断开连接最有可能包括将发送方和接收方插入和删除到某些列表中,这些列表最有可能通过QMutex
锁定来访问。 - 时间也可能“昂贵”,快速连接和断开绝对不是最佳做法。
3)你可以找到仍然使用Qt的singnal-slot系统的最不“昂贵的时间”解决方案。
可选)查看QSignalMapper
。它的设计完全符合您计划在选项1)中执行的操作。
在Emitter
和Receivers
之间进行通信有更多最佳解决方案,但作为最佳做法,我首先选择最易于使用且快速实施的选项,但是运行时间足够快的可能性(即选项3)。 )。然后,完成后,看看它是否符合您的性能要求。如果没有,并且只有那时,考虑在数据提供者中使用共享内存和互斥量 - 数据使用者体系结构(Emitter
线程在圆形列表中快速发布请求数据,而Receiver
线程只要有时间就读取它们,然后以类似的方式返回结果,而Emitter
线程不断轮询完成的结果。)