C++ 如何在C++;?

C++ 如何在C++;?,c++,multithreading,boost,synchronization,performance,C++,Multithreading,Boost,Synchronization,Performance,我有一个数据源,它不断地将数据包输入。有5个线程(A、B、C、D、E)处理数据包。请注意,这5个线程的速度完全不同,它们为每个传入的数据包生成5个不同的特性(每个线程生成1个特性) 这5个线程的速度不同:当A完成前10个包的分析时,B可能只完成了包1、包2,而C可能根本没有完成一个包 我的任务是匹配来自5个线程的结果,并在前10个数据包的所有5个特性都可用时开始最终分析 我的问题是: -如何组合来自不同线程的结果,确保只有在一定数量的结果可用时才会触发分析线程? -我似乎需要一个聚合器线程来检查

我有一个数据源,它不断地将数据包输入。有5个线程(A、B、C、D、E)处理数据包。请注意,这5个线程的速度完全不同,它们为每个传入的数据包生成5个不同的特性(每个线程生成1个特性)

这5个线程的速度不同:当A完成前10个包的分析时,B可能只完成了包1、包2,而C可能根本没有完成一个包

我的任务是匹配来自5个线程的结果,并在前10个数据包的所有5个特性都可用时开始最终分析

我的问题是: -如何组合来自不同线程的结果,确保只有在一定数量的结果可用时才会触发分析线程? -我似乎需要一个聚合器线程来检查不同缓冲区的可用性。我在考虑锁/状态。我如何实现这种涉及不同缓冲区的条件

在多线程方面完全是新手。欢迎任何建议

我使用GNU C++与Boost库。 拥有一个“聚合器”线程:该线程将从工作线程(我建议通过非阻塞线程安全队列)获取其输入,一旦“批处理”就绪,将其推送到“分析器”线程

队列提供了不阻塞任何工作者的优势:“聚合器”只需轮询工作者队列(通过条件部分)。您可以根据自己的喜好控制投票率

此解决方案解决了“同步所有”情况的问题。

拥有一个“聚合器”线程:此线程将从工作线程(我建议通过非阻塞线程安全队列)获取其输入,一旦“批处理”就绪,将其推送到“分析器”线程

队列提供了不阻塞任何工作者的优势:“聚合器”只需轮询工作者队列(通过条件部分)。您可以根据自己的喜好控制投票率


此解决方案解决了“全部同步”情况的问题。

障碍是规范的“全部同步”操作


但是,听起来您希望在关键部分中有一个“count result”变量,当完成一定数量时,该变量将递增。然后,您需要执行“阻塞直到变量等于x”。这可以通过针对计数结果变量的旋转锁来实现。

屏障是标准的“全部同步”操作


但是,听起来您希望在关键部分中有一个“count result”变量,当完成一定数量时,该变量将递增。然后,您需要执行“阻塞直到变量等于x”。这可以通过对count result变量的旋转锁来实现。

有一个存储结果的容器和一个类似这样的函数(psuedo代码):


由于互斥仅保护相当快的“添加到容器”操作,因此不应导致过度序列化。

有一个存储结果的容器和一个类似这样的函数(psuedo代码):


由于互斥仅保护相当快的添加到容器操作,因此不应导致过度序列化。

您可能需要检查您可能需要检查使用信号量和额外的布尔“完成”变量。每当一个线程完成时,它首先写下它的答案,然后写下它的“done”变量,然后调用一个“check”函数来检查所有treads“done”变量,如果它们都为真,则触发分析线程

根据您的性能权衡,您可能只希望最慢的“work”线程调用“check”函数,因此最快的线程不会一直锁定其“done”变量进行读取。当然,这取决于知道哪一个是最慢的


我不知道您的重置策略:您是希望每次等待10个新输入,还是连续分析最近的10个输入

使用信号量和额外的布尔“done”变量。每当一个线程完成时,它首先写下它的答案,然后写下它的“done”变量,然后调用一个“check”函数来检查所有treads“done”变量,如果它们都为真,则触发分析线程

根据您的性能权衡,您可能只希望最慢的“work”线程调用“check”函数,因此最快的线程不会一直锁定其“done”变量进行读取。当然,这取决于知道哪一个是最慢的

我不知道您的重置策略:您是希望每次等待10个新输入,还是连续分析最近的10个输入

一些伪代码:

worker thread: 
   -> do work, 
     -> publish result to queue
   -> 10 reached, signal my condvar 

aggregator thread: 
   -> wait on all condvars. 
   -> lock all result queues, swap in new empty ones.  
   -> do aggregation processing. 
创建新队列的原因是,聚合处理可能会导致大量锁定,如果项目被删除,则会导致无效-如果在工作线程上放置新队列,则无需担心锁定问题(尤其是聚合器不需要与工作线程共享其结果)

一些伪代码:

worker thread: 
   -> do work, 
     -> publish result to queue
   -> 10 reached, signal my condvar 

aggregator thread: 
   -> wait on all condvars. 
   -> lock all result queues, swap in new empty ones.  
   -> do aggregation processing. 

创建新队列的原因是,聚合处理可能会导致大量锁定,如果项目被删除,则会导致无效-如果在工作线程上放置新队列,则无需担心锁定问题(尤其是聚合器不需要与工作线程共享其结果)

当前的设计受到最慢计算的限制,其他线程的使用量不够

如果您想处理大量数据包,我会像这样拆分工作:

将数据包分发到N个相同的线程,该线程按顺序计算它们接收到的数据包的5个结果

每个线程将其结果数据包放入线程安全的fifo中


您的主线程读取结果,如果需要,使用数据包编号对其进行重新排序。您当前的设计受到最慢计算的限制