Fully Synchronous

by Devran Akca and Stephan Pareigis

Fully Synchronous

by Devran Akca and Stephan Pareigis

A buffer is used for communication between objects which run in different threads. A buffer wraps some shared memory or a unique pointer thereto. The buffer may be accessed by the two communication partners via reference to the buffer which is initialized via constructor argument.

A buffer is a single block of memory for a message (or unique pointer) and messages are not queued. Check out the channel if you need communication via a message queue. There are different ways to use a buffer for communication. Either it is ensured that the producer waits until the latest message has been read by the consumer, and the consumer waits until a new message has been provided by the producer. This is called fully synchronous buffer (fsb). No messages are lost or repeatedly read.

Another possibility is the contiuous write buffer, where the producer does not wait for the consumer to read and overwrites messages. Messages may be lost in this case if the consumer read slower than the producer writes. The contiuous asynchronous buffer (cab) does not wait on either side. The consumer may read the same message if no new messages are provided by the producer.

This code example shows how the full_sync_buffer is used. Three thread objects are created (producer, broker, consumer). A message is created in the producer, which is passed on to the broker which passes it on to the consumer. Two buffers are used to realize this (lines 108 and 109), which are given to the thread objects via constructor argument (lines 110 - 112). Broker and Consumer block on the get-call and wait for the message to arrive. The Producer blocks on the put-call until the receiver is ready to receive (i.e. until the buffer is empty). This way the communication is synchronized.

Once the broker has passed on the message, the producer could go on and send the next message to the broker (not shown in the code) while the consumer might still be busy with the first message. The producer needs to create new memory for each message. A unique pointer to the message is passed on between the communication partners. Be aware at this point, that the new call will take a lot of time if used frequently. It is a good idea to use a memory pool at this place.

The memory of the message is automatically cleaned up by the use of a unique pointer. This happens in the moment the unique pointer in the consumer is overwritten by the next message.

Related