简体   繁体   中英

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.

Background: I recently wrote an application where I used protobuf for communication between sockets. 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''. 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. The main idea was creating a protobuf-message instead of a whole instance of an class and pushing them to the queue. So the basic idea was to create a ''queue'' which holds a list of binary string generated using the ''protobuf'' method 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 . With Method 2, you would still use a queue, but serialize only the necessary parts of the object onto the queue.

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. Threads were invented as an optimizaion so you could share memory.

Method 1 creates an object once and destroys it once. Method 2 creates an object twice and destroys it twice. 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.

Method 1 can simply read the object since memory is shared. Method 2 must copy the object information into the buffer, then copy it back out. That's two extra copies.

Method 1 has the overhead of a queue. 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. 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.

Method 1 is shared-memory multi-threading. Method 2 is more of a distributed architecture / message-passing / IPC / COM-esque paradigm. The latter was sort of a fad in the 90's and early 2000's but has since died out.

Threads vs. message passing was actually a classical debate in OS research in the 90's. 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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