【发布时间】:2012-07-02 14:16:05
【问题描述】:
我有多个线程需要使用来自 TCP 流的数据。我希望使用共享内存中的循环缓冲区/队列从 TCP 套接字读取。 TCP 接收将直接写入循环队列。消费者将从队列中读取。
此设计应启用零复制和零锁定。但是这里有两个不同的问题。
是否可以/有效地从 TCP 套接字中仅读取 1 条逻辑消息?如果没有,并且我阅读了超过 1 条消息,我将不得不将残差从 this 复制到 this->next。
真的可以实现无锁队列吗?我知道有原子操作,但这些也可能很昂贵。因为所有的 CPU 缓存都需要失效。这将影响我所有 24 个内核上的所有操作。
我对低级 TCP 有点生疏,不太清楚如何判断消息何时完成。我是在寻找 \0 还是特定于实现?
ty
【问题讨论】:
-
您空间中的消息是什么?您有崇高的目标,但简单直接的解决方案的性能还不够吗?
-
无锁并不意味着“成本不高”,尽管在实践中无锁通常比锁定中涉及的上下文切换快几个数量级。只要您使缓冲区大小合适,就可以仅通过原子增量来实现您想要的,这是超快的,例如65536. 总而言之,我同意 Nim。
-
@Damon,有趣的是,我还没有看到一个单独依赖原子增量的环实现,可能你有一篇论文(链接)吗?我见过(并且已经做过)的唯一实现依赖于比较/交换操作..
-
如果你传递对象指针,而不是实际的批量数据,缓冲区的大小有点无关紧要——无论如何,每个缓冲区只传递 32/64 位。排队 100MB 与排队 10 个字节所用的时间相同。这实际上比一些带有狡猾的无锁指针和充斥着缓存抖动问题的讨厌的共享批量数据队列更容易管理。
-
请注意,首先考虑“批量数据”在概念上是错误的。尽管很多数据可能随时通过网络到达,但从来没有像“批量”这样的东西,绝对没有。如果有,您的系统将无法工作。进入的数据被放置在队列中并由消费者比新数据进入更快处理。总之,您的消费者必须比任何可能进入的数据都更快,具有良好的安全边际。否则,您的工作队列,无论您如何实现它,也无论您拥有多少 RAM , 难免溢出。
标签: c++ tcp circular-buffer lockless zero-copy