多线程应用程序的概念

时间:2010-03-03 00:09:13

标签: c++ multithreading winapi

我有一个小架构怀疑在单独的功能单元中组织代码(很可能是线程?)。正在开发的应用程序应该执行以下任务:

  1. 在屏幕上显示一些图像(即幻灯片)
  2. 通过USB端口从外部设备读取数据
  3. 将收到的数据与相应的图像(刺激)匹配
  4. 进行一些数据分析
  5. 绘制数据分析结果
  6. 我的想法是将应用程序组织到以下模块中:

    1. GUI线程(+图像幻灯片)
    2. USB线程缓冲接收的数据
    3. 用于分析/绘制数据的线程(绘制可能消耗更多时间的数据时不应阻止主GUI线程)
    4. 那么,您通常会对这个概念有什么看法?你觉得还有什么其他的东西可能更适合这种情况吗?

6 个答案:

答案 0 :(得分:3)

你可以将1&组合起来。 2,因为幻灯片放映功能无论如何都基本上是gui。

对于#3,您可以使用某种异步I / O方法,这样您就不需要专用轮询线程。不确定您是否可以使用USB执行此操作,但您当然可以通过串行和网络接口获得异步I / O,因此值得研究。

移动像4& 4这样的重量级任务可能是一个好主意。 5到自己的线程。如果你没有同时进行分析和绘图,可能还有一个线程。但是,您应该考虑这些活动需要多少CPU时间。如果最坏情况的分析和情节花费的时间远不到半秒,你甚至可以通过gui的调用来执行这些操作。相反,如果有时候需要更长的时间,那么单独的线程是有利的b / c您的用户不会喜欢滞后的gui。

请记住,线程的黑暗面在于协调它们的不可避免的挑战。

答案 1 :(得分:3)

由于Windows API的工作方式,特别是在用户输入和窗口所有权方面。你真的只能在一个线程上做UI。如果您尝试使用多个线程,它们最终会相互锁定,并且一次只运行一个线程。有一些专门的例外,但您必须成为API的真正才能将其删除。

因此。

  1. GUI线程,拥有Window,并处理所有用户输入。
  2. USB听线程,你知道这是否合理
  3. 用于分析/绘制数据的线程,再一次,我不能对此说话,但我怀疑他们真的会同时运行。这似乎更有可能是分析然后绘制如此1线程。
  4. 用于渲染幻灯片的帧的线程。
  5. 我不确定绘图与幻灯片放映是不是一回事,但我确实认为你可以有一个后台线程来绘制幻灯片,只要它不显示图像。 您可以在后台线程中渲染(即绘制到位图或DirectX表面),您无法在窗口中显示它。但是你可以将完成的位图交给GUI线程并让它实际显示位图。这实际上是很多视频播放代码的工作原理。

答案 2 :(得分:2)

这很大程度上取决于执行3(做一些数据分析)和4(绘制分析数据)所涉及的程度。

我的直觉是:

肯定有一个单独的线程用于从USB读取数据。假设片刻3依赖于读取数据,那么我将在与读取数据相同的线程中执行3。这将简化您在数据就绪时向GUI发送信号的过程。这也假定处理速度很快,并且不会阻塞USB端口(如何读取?IO完成端口?)。如果处理需要时间,那么你需要一个单独的线程。

同样,如果图像幻灯片处理显示需要很长时间,则应该在单独的线程中完成。如果可以根据绘图功能快速重新计算,我会将其作为主GUI的一部分。

线程的上下文切换有一些开销,并且每个线程增加了信令的复杂性。所以我只会添加一个线程来解决阻塞GUI和USB端口的问题。可以在两个线程中完成所有这些操作。

答案 3 :(得分:1)

4和5绝对是好主意。话虽如此,除非绝对必须,否则请避免使用低级线程。

我会查看Boost和Boost::Thread。它不仅使您的代码更具可移植性,而且还没有使用更简单的线程库进行线程化。

答案 4 :(得分:1)

如果您使用的是Builder 2009,则应该查看TThread。它有一些简化线程编码的东西。

答案 5 :(得分:1)

我不禁想到你可能会有点过火了。 USB端口无法真正快速地提供数据 - 它的理论带宽仅为480 Mbits /秒,而且实际上,它是一种非常罕见的USB设备,可以真正接近它。

除非您提到的分析比您所暗示的要复杂得多,否则我的猜测是单个线程可能完全足够。我认为使用重叠I / O来读取数据很困难,并且主要消息循环使用MsgWaitForMultipleObjects

在我看来,你很有可能获得很多收获的主要地方是在处理数据之后绘制数据。可能值得考虑像OpenGL或DirectX Graphics这样的绘图。特别是如果你产生相当多的输出,这可以提供真正显着的速度提升。在理想情况下,多个线程可能会将您的速度乘以可用内核的数量 - 在当今的机器上通常为2或4。绘制输出可能是工作中最慢的部分,并且硬件加速可以轻松地将其加速一个相当大的因素 - 10倍处于您通常期望的低端,而100x是相当普遍的。