繁体   English   中英

使用protobuf进行线程通信

[英]Using protobuf for thread communication

我知道关于多线程通信的讨论很多,但是我没有发现涉及protobuf的通信。

背景:我最近编写了一个应用程序,其中使用protobuf在套接字之间进行通信。 我的应用程序产生了不同的线程,这些线程应该可以相互通信。

这是通过将对象(类的实例)推送到“ std :: queue”来完成的。 因此,基本上我一个线程使用我的信息创建了一个类的实例,将其推送到“队列”,而我的其他线程则从此队列(或缓冲区)中弹出对象并进行处理。

现在我想知道使用“ protobuf”进行通信而不是实例化对象是否会更好。 主要思想是创建一个protobuf消息,而不是一个类的整个实例,并将其推入队列。 因此,基本思想是创建一个“队列”,其中包含使用“ protobuf”方法SerializeToString()生成的二进制字符串列表。

难道这是在线程之间共享数据的更干净的方式(更有效的方式)吗?

总结一下:使用方法1,可以在std::queue上使对象入队和出队。 使用方法2,您仍将使用队列,但仅将对象的必要部分序列化到队列中。

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

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

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

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

方法1具有队列的开销。 通常,队列仅具有指向该对象的指针,因此排队和出队很便宜。 队列可以在数组上实现。 方法2还具有队列的开销。 但是,数据全部存储在队列中,因此入队和出队取决于序列化数据的大小。 即使序列化的数据很小,它也不比方法1快。

方法1是共享内存多线程。 方法2更多地是一种分布式体系结构/消息传递/ IPC / COM风格的范例。 后者在90年代和2000年代初期颇为流行,但此后逐渐消失。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM