简体   繁体   English

使用protobuf进行线程通信

[英]Using protobuf for thread communication

I know there are tons of discussions about multithreading communication but I didn't find one involving protobuf for communication. 我知道关于多线程通信的讨论很多,但是我没有发现涉及protobuf的通信。

Background: I recently wrote an application where I used protobuf for communication between sockets. 背景:我最近编写了一个应用程序,其中使用protobuf在套接字之间进行通信。 My application spawn different threads and these threads should have the possibility to communicate with each other. 我的应用程序产生了不同的线程,这些线程应该可以相互通信。

This has been done by pushing objects (instances of classes) to a ''std::queue''. 这是通过将对象(类的实例)推送到“ std :: queue”来完成的。 So, I basically one thread creates an instance of a class with my information, pushing this to a ''queue'' and my other thread pops the objects from this this queue (or buffer) and processes them. 因此,基本上我一个线程使用我的信息创建了一个类的实例,将其推送到“队列”,而我的其他线程则从此队列(或缓冲区)中弹出对象并进行处理。

Now I was wondering if it wouldn't be better using ''protobuf'' for communication, instead of instantiated objects. 现在我想知道使用“ protobuf”进行通信而不是实例化对象是否会更好。 The main idea was creating a protobuf-message instead of a whole instance of an class and pushing them to the queue. 主要思想是创建一个protobuf消息,而不是一个类的整个实例,并将其推入队列。 So the basic idea was to create a ''queue'' which holds a list of binary string generated using the ''protobuf'' method SerializeToString() . 因此,基本思想是创建一个“队列”,其中包含使用“ protobuf”方法SerializeToString()生成的二进制字符串列表。

Could this be a cleaner way (and more efficient way) of sharing data beween threads? 难道这是在线程之间共享数据的更干净的方式(更有效的方式)吗?

To summarize: with Method 1, you enqueue and dequeue objects on an std::queue . 总结一下:使用方法1,可以在std::queue上使对象入队和出队。 With Method 2, you would still use a queue, but serialize only the necessary parts of the object onto the queue. 使用方法2,您仍将使用队列,但仅将对象的必要部分序列化到队列中。

In the end it sounds like there's no difference as far as the threads are concerned. 最后,听起来就线程而言没有什么区别。 It's still the same producer/consumer situation. 生产者/消费者情况仍然相同。 No matter which communication method you use, the client code doesn't change. 无论您使用哪种通信方式,客户端代码都不会更改。 Neither way is "cleaner". 两种方式都不是“清洁”。

Method 1 is more efficient. 方法1更有效。 Threads were invented as an optimizaion so you could share memory. 线程是为了优化而发明的,因此您可以共享内存。

Method 1 creates an object once and destroys it once. 方法1创建一次对象,然后销毁一次。 Method 2 creates an object twice and destroys it twice. 方法2创建一个对象两次并将其销毁两次。 The object is created by the producer thread, which then serializes it and destroys the object. 该对象由生产者线程创建,然后将其序列化并销毁该对象。 The object is re-created from the deserialized data by the consumer thread, which uses it and then destroys it. 使用者线程根据反序列化的数据重新创建对象,该线程使用它然后销毁它。 Even if Method 2 could somehow optimize away the object instantiation (eg using a char array instead of a string object), you could apply the same optimization to Method 1. 即使方法2可以以某种方式优化对象实例化(例如,使用char数组而不是string对象),也可以将相同的优化应用于方法1。

Method 1 can simply read the object since memory is shared. 由于共享内存,方法1可以简单地读取对象。 Method 2 must copy the object information into the buffer, then copy it back out. 方法2必须将对象信息复制到缓冲区中,然后再将其复制回来。 That's two extra copies. 那是两个额外的副本。

Method 1 has the overhead of a queue. 方法1具有队列的开销。 Typically the queue just has a pointer to the object, so enqueuing and dequeuing is cheap. 通常,队列仅具有指向该对象的指针,因此排队和出队很便宜。 The queue can be implemented over an array. 队列可以在数组上实现。 Method 2 also has the overhead of a queue. 方法2还具有队列的开销。 However, the data is all stored on the queue, so enqueuing and dequeuing depends on the size of the serialized data. 但是,数据全部存储在队列中,因此入队和出队取决于序列化数据的大小。 Even if the serialized data is small, it's not faster than Method 1. 即使序列化的数据很小,它也不比方法1快。

Method 1 is shared-memory multi-threading. 方法1是共享内存多线程。 Method 2 is more of a distributed architecture / message-passing / IPC / COM-esque paradigm. 方法2更多地是一种分布式体系结构/消息传递/ IPC / COM风格的范例。 The latter was sort of a fad in the 90's and early 2000's but has since died out. 后者在90年代和2000年代初期颇为流行,但此后逐渐消失。

Threads vs. message passing was actually a classical debate in OS research in the 90's. 线程与消息传递实际上是90年代OS研究中的经典辩论。 If you want to learn more about that, you should read about the history of micro-kernels. 如果您想了解更多有关此的内容,则应阅读有关微内核的历史。 A lot of effort was put into optimizing message-passing, but in the end, micro-kernels could never match the performance of monolithic kernels 在优化消息传递方面付出了很多努力,但最终,微内核永远无法匹敌单片内核的性能。

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

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