c++中Linux线程间的高性能消息传递
linux high performance message passing between threads in c++
假设我有一个进程产生2个线程
第一个线程在一个紧循环中监听UDP端口上的数据包事件。第二个线程是接收这个UDP包中包含的字节,并解析它/做一些事情。
谁能推荐一种比使用Linux消息队列更快的方法?我认为它们很慢,因为它们在写入队列时复制字节,在从队列 读取时再次复制字节。我知道zeromq库,但有没有一种圆滑的方法来做到这一点,而没有这种开销?我意识到我可以在两个线程之间使用tcp/ip套接字进行简单的排队通信,但是有更快的方法吗?
我想也许是一个环缓冲区在内存之间的线程和互斥锁用来控制指针到最近更新的元素之间共享?
有人有什么想法吗?
我能想到的最有效的方法是使用一个链表、一个互斥锁和一个条件变量:
-
线程A:
- 分配一个UDP -packet-buffer对象(该对象应包含
previous
和next
指针,以及用于存储UDP数据的字节数组) -
recv()
UDP数据到对象的字节数组 - 锁定互斥锁
- 将udp-packet-buffer对象附加到链表的尾部
- 解锁互斥锁
- 表示条件变量
- goto 1
- 分配一个UDP -packet-buffer对象(该对象应包含
-
线程B:
- 等待条件变量(直到条件变量发出信号)
- 锁定互斥锁
- 将下一个udp-packet-buffer从链表的头部弹出
- 解锁互斥锁 解析/处理UDP -packet-buffer对象中的UDP数据
- 删除udp-packet-buffer对象
- goto 1
这给了你一个零拷贝通信机制。持有互斥锁所花费的时间是最小的,所以争用也应该很低。
如果你想进一步优化,你可以让线程B一次从链表中抓取所有的项目,而不是一次只弹出一个——这是可以在O(1)时间内用链表完成的。然后让线程A在添加最新的udp-packet-buffer对象之前,仅当链表为空时才通知条件变量。这将减少线程在重载时必须锁定/解锁/发出信号的次数。
当我来到这个页面时,这个非常好的答案也是我所期望的https://stackoverflow.com/a/8567548/2893944
一个可能有帮助的小注意事项:摆脱动态内存分配也是一个可以提高性能和避免内存碎片的点(例如:使用静态数组,使用内存池)。
(这应该是一个评论,但不够声誉)
checkout http://www.boost.org/libs/circular_buffer/我使用boost::array<1500>作为一个项目中2个线程之间的通信点,我看不出它在任何方面都很慢。其中第一个线程正在接受UDP包,并快速检查一些位是否应该将其放在缓冲区中。它可以复制进出,但当我配置文件时,它甚至不会显示。
编辑:BoundedBuffer示例是有趣的位http://www.boost.org/libs/circular_buffer/doc/circular_buffer.html#boundedbuffer
为了获得最佳性能,您需要固定大小、无锁、单写、单读的队列。
这篇代码项目文章出现在一个快速谷歌似乎合理,并解释了一些来龙去脉。
我不知道你的用例是什么-但是如果采取了这样一个冗长的措施-你的软件(和环境)需要考虑如何处理由缓慢的消费者引起的满队列将导致数据丢失的情况。
- Libmosquitto publish 不会将所有消息传递到 Azure IoT Hub
- 线程消息传递或更好:在"大师班"中访问其他班级的成员
- 如何在 boost::asio 中将打包的结构作为消息传递?(无序列化)
- "Guaranteed Delivery"消息传递 - 我应该使用 MQTT 还是 ZeroMQ?
- 核心消息传递中未处理的异常.dll在程序关闭期间
- Microsoft具有本机消息传递和非持久连接的边缘扩展不起作用
- Firebase C 云消息传递背景问题
- 从客户端到浏览器的CEF中的消息传递序列化
- 我们是否可以使用 FireBase 云消息传递来发送或接收消息,或者在 Windows 桌面/控制台或 Linux 控制
- 如何将WM_KEYDOWN消息传递到 IWebBrowser2 实例
- 如何在 GNU Radio 中实现消息传递
- msgpack:C++和Java之间的消息传递
- 增强ASIO和线程之间的消息传递
- 交流时Chrome本机消息传递错误
- 多线程C++消息传递
- 跨平台最佳 MVC 模型到控制器消息传递方法(C#、Objective-C++)
- 如何在Chrome原生消息传递扩展的本机应用程序中使用本机主机消息
- 移动窗口(),跳过,躲避或绕过消息传递
- 无效输入会导致多语言 JSON 消息传递系统中的身份验证绕过
- c++中Linux线程间的高性能消息传递