我正在设计一个连接到一个或多个数据馈送流的系统,并对数据进行一些分析,而不是根据结果触发事件。在典型的多线程生产者/消费者设置中,我将有多个生产者线程将数据放入队列,多个消费者线程读取数据,消费者只对最新的数据点加上 n 个点感兴趣。如果慢的消费者跟不上生产者线程将不得不阻塞,当然当没有未处理的更新时消费者线程将阻塞。使用带有读/写锁的典型并发队列会很好地工作,但数据进入的速度可能会很大,所以我想减少我的锁定开销,尤其是生产者的写锁。我认为我需要一个循环无锁缓冲区。
现在有两个问题:
循环无锁缓冲区是答案吗?
如果是这样,在我推出自己的产品之前,你知道任何符合我需要的公共实施吗?
任何实现循环无锁缓冲区的指针总是受欢迎的。
顺便说一句,在 Linux 上用 C++ 执行此操作。
一些附加信息:
响应时间对我的系统至关重要。理想情况下,消费者线程将希望尽快看到任何更新,因为额外的 1 毫秒延迟可能会使系统一文不值,或者价值大大降低。
我倾向于的设计思想是一个半无锁循环缓冲区,其中生产者线程尽可能快地将数据放入缓冲区中,让我们调用缓冲区 A 的头部,除非缓冲区已满,否则不会阻塞,当A 与缓冲区 Z 的末端相遇。消费者线程将分别持有两个指向循环缓冲区的指针 P 和 P n,其中 P 是线程的本地缓冲区头,P n是 P 之后的第 n 项。每个消费者线程将推进其 P和 P n一旦它完成处理当前 P 并且缓冲区指针 Z 的末尾以最慢的 P n前进. 当 P 赶上 A 时,这意味着不再需要处理新的更新,消费者旋转并忙于等待 A 再次前进。如果消费者线程旋转时间过长,它可以进入睡眠状态并等待条件变量,但我可以接受消费者占用 CPU 周期等待更新,因为这不会增加我的延迟(我将拥有更多的 CPU 内核比线程)。想象一下你有一个环形轨道,生产者跑在一堆消费者前面,关键是调系统,让生产者通常跑在消费者前面几步,而这些操作大部分都可以使用无锁技术完成。我知道要正确执行实施的细节并不容易……好吧,非常难,这就是为什么我想在自己犯一些错误之前从别人的错误中吸取教训。