Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 多线程应用程序概念_C++_Multithreading_Winapi - Fatal编程技术网

C++ 多线程应用程序概念

C++ 多线程应用程序概念,c++,multithreading,winapi,C++,Multithreading,Winapi,我对在单独的功能单元(很可能是线程?)中组织代码有一点架构上的疑虑。正在开发的应用程序应执行以下任务: 在屏幕上显示一些图像(即幻灯片) 通过USB端口从外部设备读取数据 将接收到的数据与相应的图像(刺激)匹配 做一些数据分析 绘制数据分析的结果 我的想法是将应用程序组织成以下模块: GUI线程(+图像幻灯片) USB线程缓冲接收到的数据 用于分析/打印数据的线程(打印数据时不应阻止主GUI线程,这可能会占用更多时间) 那么,你对这个概念一般怎么看?您认为还有什么东西更适合这个特定场景吗?您可能

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

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

  • GUI线程(+图像幻灯片)
  • USB线程缓冲接收到的数据
  • 用于分析/打印数据的线程(打印数据时不应阻止主GUI线程,这可能会占用更多时间)

  • 那么,你对这个概念一般怎么看?您认为还有什么东西更适合这个特定场景吗?

    您可能可以将1和2结合起来,因为幻灯片放映功能本质上是面向gui的

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

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


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

    4和5绝对是好主意。也就是说,避免使用低级线程,除非您必须这样做


    我会检查一下Boost和Boost。它不仅使您的代码更易于移植,而且我还没有使用更简单的线程库

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

    我的直觉是:

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

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


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

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

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

    所以

  • GUI线程,拥有窗口,并处理所有用户输入
  • USB监听线程,你会比我更清楚这是否有意义
  • 用于分析/绘制数据的线程,再一次,我不能谈论这一点,但我怀疑它们是否真的会同时运行。这似乎更可能是它将分析,然后绘图,所以1线程
  • 用于渲染幻灯片帧的线程 我不确定如何绘制与幻灯片不同,但我确实认为,只要幻灯片不显示图像,就可以使用背景线程绘制幻灯片。
    可以在背景线程中渲染(即绘制位图或DirectX曲面),但不能在窗口中显示。但是您可以将完成的位图交给GUI线程,让它实际显示位图。这就是很多视频播放代码的工作原理

    我忍不住想,你可能有点过火了。USB端口不能很快地传输数据——理论上它的带宽只有480 Mbits/秒,实际上,它是一种非常罕见的USB设备,可以非常接近这一点

    除非你提到的分析比你暗示的要复杂得多,否则我的猜测是一个线程可能就足够了。我会认真考虑使用重叠I/O来读取数据,并对主消息循环使用
    MsgWaitForMultipleObjects

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