Quick summary ↬ Here is an example of a C++ threading code that demonstrates how to use multiple threads and synchronize them using condition variable. This is basic producer-consumer scenario of how Apache Kafka streams data.
Beautiful code #8
|
|
Beautiful code #8 explanation
This code demonstrates a producer-consumer scenario using a fixed-size buffer and condition variables to synchronize the producer and consumer threads. Let’s go through the code and understand how it works:
-
We include the necessary header files for working with threads, queues, mutexes, and condition variables.
-
We declare a shared buffer as a queue to hold the produced items. We also define the
buffer_size
constant to specify the maximum size of the buffer. -
We define a mutex (mtx) to protect access to the buffer and two condition variables:
buffer_not_full
to signal that the buffer is not full and the producer can produce items, andbuffer_not_empty
to signal that the buffer is not empty and the consumer can consume items. -
The producer function represents the producer thread. It produces items by pushing integers from 1 to 10 into the buffer. Before modifying the buffer, it acquires a unique lock on the mutex using
std::unique_lock<std::mutex> lock(mtx)
. -
To avoid producing items when the buffer is full, the producer thread waits for the
buffer_not_full
condition variable to notify it that the buffer has space available. It uses the lambda function[] { return buffer.size() < buffer_size; }
as the predicate to check if the buffer is not full. -
Once the producer thread is awakened and the buffer has space available, it pushes the item into the buffer, prints the produced item, and then notifies the
buffer_not_empty
condition variable to indicate that there are items in the buffer for the consumer thread to consume. -
The consumer function represents the consumer thread. It repeatedly waits for the
buffer_not_empty
condition variable to notify it that the buffer has items available for consumption. -
When the buffer_not_empty condition variable notifies the consumer thread, it acquires a unique lock on the mutex and checks if the buffer is not empty by using the lambda function
[] { return !buffer.empty(); }
as the predicate. -
If the buffer is not empty, the consumer thread retrieves the front item from the buffer, pops it, and prints the consumed item.
-
Finally, the consumer thread notifies the
buffer_not_full
condition variable to indicate that there is space available in the buffer for the producer thread to produce more items. -
In the main function, we create the producer and consumer threads and wait for them to finish using the join function.
Overall, this code demonstrates how condition variables can be used in a producer-consumer scenario to synchronize the producer and consumer threads and ensure that the buffer doesn’t become full or empty.
You will also like — More Articles
https://fluentprogrammer.com/beautiful-code-1-using-define-templates-r-value-reference/ https://fluentprogrammer.com/beautiful-code-2-enable_if_t-template-inside-a-template/ https://fluentprogrammer.com/beautiful-code-3-no_unique_address_cpp_20-feature/ http://fluentprogrammer.com/beautiful-code-4-any_of-none_of-all_of/ https://fluentprogrammer.com/beautiful-code-5-for_each-optional/