使用Protobuf进行线程通信



我知道有很多关于多线程通信的讨论,但我没有找到涉及Protobuf进行通信的讨论。

背景:我最近写了一个应用程序,在该应用程序中,我使用Protobuf进行了插座之间的通信。我的应用程序产生了不同的线程,这些线程应该有可能相互通信。

这是通过将对象(类的实例(推向'std :: queue''来完成的。因此,我基本上一个线程与我的信息创建了一个类的实例,将其推到"队列",而我的另一个线程则弹出了此队列(或buffer(的对象并处理它们。

现在,我想知道使用" Protobuf"进行通信而不是实例化对象,这是否会更好。主要想法是创建一个Protobuf-Message,而不是将班级的整个实例推到队列。因此,基本思想是创建一个"队列",该"队列"保留了使用" protobuf"'方法SerializeToString()

生成的二进制字符串列表。

这是线程之间共享数据的一种更干净的方式(和更有效的方法(吗?

汇总:使用方法1,您可以在std::queue上加入并脱离对象。使用方法2,您仍然使用队列,但仅序列化对象的必要部分到队列中。

最后,就线程而言,听起来似乎没有区别。它仍然是同一生产者/消费者的情况。无论您使用哪种通信方法,客户端代码都不会更改。两种方式都是"清洁器"。

方法1更有效。线程是作为优化发明的,因此您可以共享内存。

方法1一次创建一个对象并将其拆除一次。方法2创建了两次对象并将其摧毁两次。该对象由生产者线程创建,然后将其序列化并破坏对象。该对象是由消费者线程重新创建的,该数据使用它,然后使用它然后将其销毁。即使方法2可以以某种方式优化对象实例化(例如,使用char数组而不是string对象(,您也可以将相同的优化应用于方法1。

方法1可以简单地读取对象,因为内存已共享。方法2必须将对象信息复制到缓冲区中,然后将其复制回。那是两个额外的副本。

方法1具有队列的开销。通常,队列只有一个指向对象的指针,因此重新定居和脱水很便宜。队列可以通过数组实现。方法2还具有队列的开销。但是,数据全部存储在队列上,因此起重和脱水取决于序列化数据的大小。即使序列化数据很小,它也不比方法1更快。

方法1是共享内存的多线程。方法2更多是分布式体系结构/消息通话/IPC/Com-Quep范式。后者在90年代和2000年代初有点流行,但此后消失了。

线程与消息传递实际上是90年代OS研究中的经典辩论。如果您想了解更多有关此信息的信息,则应阅读有关微分的历史。为了优化消息而付出了很多努力,但最终,微包装永远无法与单片内核的性能相匹配

最新更新