【问题标题】:Threading - The fastest way to handle reoccuring threads?线程 - 处理重复出现的线程的最快方法?
【发布时间】:2015-12-09 22:05:27
【问题描述】:

我正在为具有非常快的线速度的工业机器编写我的第一个线程应用程序。我将 MFC 用于 UI,一旦用户按下“开始”机器按钮,我需要同时执行三个操作。我需要非常快速地收集数据、处理数据并输出结果,并检查用户是否已将机器“关闭”。当我说得很快时,我希望执行的分析部分花费的时间最长,并且需要在一秒钟内完成。我最关心的是与线程相关的开销消除。实现以下循环的最快方法是什么:

void Scanner(CString& m_StartStop) {

    std::thread Collect(CollectData);

    while (m_StartStop == "Start") {

         Collect.join();
         std::thread Analyze(AnalyzeData);
         std::thread Collect(CollectData);

         Analyze.join();
         std::thread Send(SendData);
         Send.join();
     }
}

我意识到这个示例可能有点离题,但希望它能够理解这一点。我应该创建三个线程并暂停它们而不是一遍又一遍地创建和加入它们吗?此外,我有点不清楚 UI 是否需要自己的线程,因为用户需要能够随时暂停或停止线路。

如果有人想知道为什么需要线程而不是顺序,答案是机器的线速度将导致需要在分析第一部分时收集第二部分的数据。每 1 秒相当于这台机器向下移动 3 英尺的线性零件。

【问题讨论】:

  • 所有 UI 操作必须在同一个线程中进行,Windows 未设置为以任何其他方式工作。并且任何复杂的数据结构,即使是像 CString 这样简单的数据结构,也需要防止线程之间同时访问。
  • 我明白,我想我真正要问的是 UI 是父线程还是只是另一个子线程。
  • MFC 将假定它是从父线程运行的,为了避免麻烦,坚持这样做是最安全的。
  • 有道理。谢谢!

标签: c++ multithreading mfc


【解决方案1】:

在考虑实现之前先考虑功能问题。

因此,我们需要收集、分析和发送到其他地方的连续数据流,并有一个能够停止或暂停流程的监督点。

  • 集合应受输入流的限制
  • 分析只能受 CPU 限制
  • 发送应该是io绑定的

您只需要确保最慢的部分必须是收集。

这是线程的正确用例。实现可以使用:

  • 输入缓冲区池将由收集任务填充并由分析任务使用
  • 一个线程连续:
    • 控制是否应该退出(专用变量)
    • 从池中获取输入对象
    • 用数据填充它
    • 将其传递给分析任务
  • 一个线程连续

    • 等待收集任务中的第一个输入对象和退出请求
    • 分析对象并准备输出
    • 发送输出

    可选地,您可以有一个单独的线程来处理输出。在这种情况下,最后几行变为

    • 将输出对象传递给发送任务

    我们必须添加:

  • 一个线程连续

    • 等待分析任务的第一个输出对象和退出请求
    • 发送输出

并且您必须提供一种方法来发出暂停或退出请求的信号,可以使用完全外部的程序和信号机制,也可以使用 GUI 线程

【讨论】:

    【解决方案2】:

    您需要的任何线程都应该已经在运行,等待工作。您不应创建或加入线程。

    如果作业 A 必须在作业 B 开始之前完成,作业 A 的完成应该触发作业 B 的开始。也就是说,当执行作业 A 的线程完成作业 A 时,它应该自己执行作业 B,或者触发作业 B 的调度。不应该有其他线程正在等待作业 A 完成,以便它可以启动作业 B。

    【讨论】:

    • 也许我在传达我的问题方面效率低下。在第一个执行周期中,B 正在等待 A。但在第二个或更进一步的周期中,A 正在收集信息,而 B 正在分析来自 A 的前一个周期。它们必须同时工作,因为两个操作没有足够的时间来执行按顺序完成。
    • 那么收集信息的代码应该在完成收集信息后调度对信息的分析。你不应该让一个线程等待某事发生,以便它可以告诉另一个线程做某事。
    • 好的,谢谢。这很有帮助。所以基本上,我将这个答案解释为,当每个线程完成其任务时,它应该被销毁。然后应该在短时间内创建另一个来执行相同的任务。那是对的吗?此外,就创建线程和销毁线程的时间而言,开销是否很大?请记住,我将与时间赛跑。仅供参考,每 8 毫秒会有一个 168 字节的信息块。
    • 这些块将被收集大约 1 秒,然后发送到分析部分。然后重复。
    • @bluebass44 不,线程不应该被破坏。线程应该继续做下一件需要做的事情。为什么要破坏一个完美的线程?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-11
    • 2017-01-31
    • 1970-01-01
    • 2011-09-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多