Skip to content

Understanding Producer-Consumer and Publish-Subscribe Patterns in C

License

Notifications You must be signed in to change notification settings

dezashibi-c/a-prod_cons_vs_pub_sub_in_c

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Understanding Producer-Consumer and Publish-Subscribe Patterns in C

Introduction

In multi-threaded programming, two common patterns emerge to manage the flow of data between threads: the producer-consumer pattern and the publish-subscribe (pub/sub) pattern. Although both patterns aim to coordinate the efforts of multiple threads, they serve different purposes and employ different mechanisms. In this discussion, I would like to implement these patterns and explore their implementations using my own cross platform multi threading library DThreads, and highlight their key differences and use cases.

All codes are tested on Windows and WSL using both zig cc and gcc, also no memory leaked by checking through valgrind.

Producer-Consumer Pattern

The producer-consumer pattern is a classic synchronization problem where one or more producer threads generate data and place it in a shared buffer, while one or more consumer threads remove and process this data. The primary challenge is ensuring that the buffer is accessed in a thread-safe manner, preventing race conditions and ensuring data integrity.

In this pattern, a buffer serves as the shared resource where producers place items and consumers retrieve them. The implementation utilizes mutexes to lock the buffer during access, preventing simultaneous modifications by multiple threads. Condition variables are employed to synchronize the threads, ensuring that producers wait when the buffer is full and consumers wait when it is empty.

A common scenario for the producer-consumer pattern is a multi-threaded task queue, where producers generate tasks and add them to the queue, and consumers remove and execute these tasks. This pattern is particularly useful in applications that require balanced workloads, such as web servers and parallel processing systems.

👉 Example Implementation: please refer to producer_consumer.c

Publish-Subscribe Pattern

The publish-subscribe pattern, commonly known as pub/sub, decouples the producers (publishers) and consumers (subscribers) of data. Publishers send messages to an intermediary, often called a message broker, which then distributes these messages to interested subscribers. This pattern is widely used in event-driven architectures and systems where multiple components need to react to changes or events.

Unlike the producer-consumer pattern, pub/sub does not involve a shared buffer. Instead, the message broker handles the distribution of messages. This decoupling allows publishers and subscribers to operate independently, making the system more flexible and scalable.

In the pub/sub model, publishers generate messages or events and send them to the broker. Subscribers register their interest in specific types of messages with the broker, which ensures that only relevant messages are delivered to each subscriber. This pattern is particularly effective for applications that require real-time notifications, such as news feeds, stock tickers, and IoT systems.

👉 Example Implementation: please refer to publisher_subscriber.c

Key Differences and Use Cases

The producer-consumer and pub/sub patterns are designed for different types of communication between threads. Here are some key differences and typical use cases for each:

  1. Communication Model:

    • Producer-Consumer: Direct interaction via a shared buffer, with tightly coupled producers and consumers.
    • Pub/Sub: Indirect interaction via a message broker, with loosely coupled publishers and subscribers.
  2. Synchronization:

    • Producer-Consumer: Relies on mutexes and condition variables to manage access to the shared buffer.
    • Pub/Sub: Uses the message broker to handle message distribution, often asynchronously.
  3. Use Cases:

    • Producer-Consumer: Ideal for task queues, data processing pipelines, and situations where tasks are handed off directly between threads.
    • Pub/Sub: Suitable for event-driven systems, real-time notifications, and scenarios where multiple components need to respond to events.

Conclusion

The producer-consumer and publish-subscribe patterns are essential in multi-threaded programming for different scenarios.

The producer-consumer pattern is ideal for direct hand-off of tasks between threads, making it useful for scenarios like task queues.

On the other hand, the pub/sub pattern is excellent for event-driven architectures, where multiple components need to respond to changes or events without being tightly coupled.

NOTE (Debug Messages): You can disable debug messages by removing -DDTHREAD_DEBUG from line 20 of Makefile.

License

Creative Commons Attribution-NonCommercial 4.0 International (CC BY-NC 4.0) License.

Please refer to LICENSE file.

About

Understanding Producer-Consumer and Publish-Subscribe Patterns in C

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors