2012-01-08 47 views
1

我有一个情况,我有一个发射器对象和一组接收器。接收器属于同一类,实际上代表了一组相同类型的设备。我正在使用Qt框架。动态地向一个对象发射信号

  • 发射器本身首先获取信号,从其中一个设备获取信息。

  • 在相应的插槽中,发射器必须检查哪些接收器已准备就绪,然后发送自己的信号以请求数据到其中一个设备(以先准备好的为准)。

发射器接收信号的速度非常快,大约为几毫秒。有三种方法我可以考虑只从其中一个设备安全地请求数据(这些设备存在于它们自己的线程中,所以我需要一个线程安全的机制)。设备数量不是静态的,可以改变。设备总数很少(绝对在5-6之下)。

1)连接到所有设备时,他们被添加或删除。发出一个请求并让设备对象自己过滤出请求是否使用某个特定的设备标签。这种方法很好,因为发生检查的请求位置将在专用线程的上下文中执行,但随着设备数量的增加而浪费。

2)当需要发送请求时,在发射器中动态连接和断开连接。

3)当需要发送请求时,使用QMetaObject :: invokeMethod()。

表现很重要。有谁知道哪种方法是“最好的”,或者是否有更好的方法?

问候

的PRI

注:为了澄清:从发射器应用程序获取的信号,通过查询设备以获取信息。疯狂的ASCII艺术去:

(APP)< ---->(发射器)< ------>(接收器)< - | - >物理设备

回答

0

根据这些信息,你提供了我仍然会推荐的Reactor实现。如果你不使用ACE,那么你可以实现你自己的。基本架构如下:

  1. 使用select当从应用程序接收到信号或数据时唤醒。
  2. 如果有一个插座准备发送列表上,则你随便挑一个,并将其发送数据
  3. 当数据发送Receiver从设置插座/可用
  4. 在处理数据处理程序的删除自身Reciever将自己重新注册到可用收件人列表。

我建议ACE的原因是因为它具有最简单的Reactor模式实现之一。

+0

我的问题措辞严重,并更新它来澄清一点。 1)是的,但现在我只关心从应用程序到接收器的信号流。 2)接收器是相同的,但不共享数据。 ACE好像对此可能是过度的。 – Prismatic 2012-01-09 00:05:18

+0

@Pris Reactor即使不与'ACE'一起工作,我仍在调整答案。 – Karlson 2012-01-09 00:32:18

0

我很喜欢这里是多线程环境。

如果是,那么答案为您的具体问题之间仅限于Qt的信号/槽系统:

1)绝对不是要走的路。在从Emitter发出的事件中,等于Receivers的事件总数将排队等待设备的线程事件循环,则一旦线程到达那些事件,就会发生相同数量的时隙调用。即使大部分在第一行中丢失的只是if(id!=m_id) return;,但它在Qt的核心中仍然有很多事情发生。在您的一个插槽中放置一个由Qt::QueuedConnection信号引发的断点,然后通过查看实际堆栈跟踪来验证此断点。从xyEventLoop::processEvents(...)来看,它通常至少有4次来电,所以“刚回来”在时间上绝对不是“免费”的。 2)不确定Qt的内部实现是如何实现的,但是从我所知的连接和断开连接中,很可能包括将发送者和接收者插入和删除某些列表,这些列表最有可能通过QMutex锁定进行访问。 - 也可能在时间上是“昂贵的”,并且快速连接和断开绝对不是最佳实践。

3)可能是至少“昂贵的时间明智”的解决方案,你可以发现,仍然使用Qt的singnal插槽系统。可选)QSignalMapper。它的设计完全符合您在选项1)中的计划。

有更优化的解决方案您EmitterReceivers之间的沟通,但我会首先选择最易于使用和快速的执行选项最好的做法,但有足够快,运行 - 一个机会时间(即选项3)。 )。然后,完成后,看看它是否符合您的性能要求。如果没有,并且只有这样,才考虑在数据提供者中使用共享内存和数据提供者互斥体 - 数据使用者体系结构(Emitter线程在循环列表中快速发布请求数据,而Receiver线程只要有时间就读取它们,然后发布结果回到了类似的方式,而Emitter线程不断调查已完成的结果。)