代码之家  ›  专栏  ›  技术社区  ›  Adi

多线程应用程序概念

  •  2
  • Adi  · 技术社区  · 16 年前

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

    1. 在屏幕上显示一些图像(即幻灯片)
    2. 通过USB端口从外部设备读取数据
    3. 将接收到的数据与相应的图像(刺激)匹配
    4. 绘制数据分析的结果

    我的想法是将应用程序组织成以下模块:

    1. GUI线程(+图像幻灯片)
    2. USB线程缓冲接收到的数据

    那么,你对这个概念一般怎么看?您是否认为在这个特定场景中还有其他更合适的方法?

    6 回复  |  直到 10 年前
        1
  •  2
  •   David L Morris    16 年前

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

    我的直觉是:

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

    同样,如果图像幻灯片处理显示需要很长时间,则应在单独的线程中完成。如果这可以很快地重新计算,比如在一个绘画函数中,我会把它作为主GUI的一部分。

    线程的上下文切换会带来一些开销,对于每个线程,都会增加信令的复杂性。所以我只想添加一个线程来解决GUI和USB端口的阻塞问题。可能只需要两个线程就可以完成所有这一切。

        2
  •  3
  •   JustJeff    16 年前

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

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

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

        3
  •  3
  •   John Knoeller    16 年前

    因为Windows API的工作方式,特别是在用户输入和窗口所有权方面。您实际上只能在单个线程上执行UI。如果您尝试使用多个线程,它们只会互相锁定,一次只运行一个线程。有一些特殊的例外,但你必须是一个真正的 主人 API的一部分来实现它。

    1. GUI线程,拥有窗口,并处理所有用户输入。
    2. USB监听线程,你会比我更清楚这是否有意义
    3. 用于分析/绘制数据的线程,再一次,我不能谈论这一点,但我怀疑它们是否真的会同时运行。这似乎更可能是它将分析,然后绘图,所以1线程。

    我不确定如何绘制与幻灯片不同,但我确实认为您可以有一个用于绘制幻灯片的背景线程 只要它不显示图像 . 可以在背景线程中渲染(即绘制位图或DirectX曲面),但不能在窗口中显示。但是您可以将完成的位图交给GUI线程,让它实际显示位图。这就是很多视频播放代码的工作原理。

        4
  •  1
  •   Xorlev    16 年前

    Boost::Thread . 它不仅使您的代码更易于移植,而且我还没有使用更简单的线程库。

        5
  •  1
  •   Gregor Brandt    16 年前

        6
  •  1
  •   Jerry Coffin    16 年前

    带宽只有480 Mbits/秒,实际上,这是一个非常罕见的USB设备,可以真正达到这一点。

    MsgWaitForMultipleObjects 对于主消息循环。

    在我看来,你很有可能获得很多东西的主要地方是在数据处理后绘制数据。也许值得考虑使用类似OpenGL或DirectX图形的工具来绘制图形。特别是如果你正在产生相当多的输出,这可以给一个真正实质性的速度提高。在理想情况下,多线程可能会将您的速度乘以可用内核的数量——在今天的机器上通常是2或4个。绘制输出可能是这项工作中最慢的部分,硬件加速可以很容易地将速度提高一个相当大的因数——10倍是您通常期望的低端,100倍是相当常见的。