Skip to content

Array-Based MPMC Blocking Queue

In this task, you'll implement a fixed-size, thread-safe circular buffer queue that supports:

  • Multiple producers and consumers
  • Blocking behavior when full (on push)
  • Blocking behavior when empty (on pop)

This is a foundational component in high-throughput systems like messaging queues, thread pools, and low-latency pipelines.


Goals

  • Use a fixed-size buffer (std::vector)
  • Wrap around using (index + 1) % capacity
  • Use std::mutex and two std::condition_variables:
    • One to block producers when full
    • One to block consumers when empty

Functional Requirements

  • push() should block when the buffer is full
  • pop() should block when the buffer is empty
  • Thread-safe access by multiple producer/consumer threads
  • Use only one mutex to guard shared state

Hints

  • Use a size_ variable to track the number of items
  • Use head_ and tail_ to mark pop/push positions
  • Wrap around with modulus
  • Notify the correct waiting thread (cv_not_empty_ or cv_not_full_) after mutation

This model is blocking and safe --- ideal before transitioning to lock-free queues.

Implement a fixed-size blocking queue using an array with multiple producers and consumers.

cpp
#include <mutex>
#include <condition_variable>
#include <vector>

template <typename T>
class ArrayBlockingQueue {
public:
    ArrayBlockingQueue(size_t capacity)
        : buffer_(capacity), capacity_(capacity), head_(0), tail_(0), size_(0) {}

    void push(const T& item) {
        // TODO
    }

    T pop() {
        // TODO
        return T{};
    }

private:
    std::vector<T> buffer_;
    size_t capacity_;
    size_t head_;
    size_t tail_;
    size_t size_;
    std::mutex mtx_;
    std::condition_variable cv_not_full_;
    std::condition_variable cv_not_empty_;
};