Untitled

mail@pastecode.io avatar
unknown
plain_text
2 years ago
2.4 kB
3
Indexable
Never
#define MAX_SIZE 100
#define PRODUCERS 2
#define CONSUMERS 1
#include <vector>
#include <condition_variable>
#include <cstdlib>
#include <iostream>
#include <thread>
#include <string>
#include <sstream>

using namespace std;

string empty("");

class RingBuffer
{
private:
    size_t readPos;
    size_t writePos;
    size_t numFull;
    size_t totalSize;
    vector<int> buffer;

public:
    RingBuffer()
    {
        readPos = 0;
        writePos = 0;
        numFull = 0;
        totalSize = MAX_SIZE;
        buffer = vector<int>(totalSize, 0);
    }

    void push(int data)
    {
        buffer[writePos] = data;
        writePos++;
        writePos %= totalSize;
        numFull++;
    }

    int pop()
    {
        int data = buffer[readPos];
        readPos++;
        readPos %= totalSize;
        numFull--;
        return data;
    }

    bool empty() const
    {
        return numFull == 0;
    }

    bool full() const
    {
        return numFull == totalSize;
    }
};

condition_variable cv_avail, cv_occ;
mutex m;

RingBuffer rb;

int available_slots = MAX_SIZE;
int occupied_slots = 0;

void producer(int idx)
{
    while (true)
    {
        unique_lock<mutex> ul(m);
        cv_avail.wait(ul, []()
                      { return available_slots > 0; });
        int data = rand() % 1000;
        stringstream ss(empty);
        ss << idx << " Producer produced: " << data << "\n";
        cout << ss.str();
        rb.push(data);
        occupied_slots++;
        available_slots--;
        ul.unlock();
        cv_occ.notify_all();
    }
}

void consumer(int idx)
{
    while (true)
    {
        unique_lock<mutex> ul(m);
        cv_occ.wait(ul, []()
                    { return occupied_slots > 0; });
        int data = rb.pop();
        occupied_slots--;
        available_slots++;
        cv_avail.notify_all();
        ul.unlock();
        stringstream ss(empty);
        ss << idx << " Consumer consumed: " << data << "\n";
        cout << ss.str();
    }
}

int main()
{
    vector<thread> producers_consumers;
    for (int i = 0; i < PRODUCERS; i++)
    {
        producers_consumers.push_back(thread(producer, i));
    }

    for (int i = 0; i < CONSUMERS; i++)
    {
        producers_consumers.push_back(thread(consumer, i));
    }

    for (int i = 0; i < producers_consumers.size(); i++)
    {
        producers_consumers[i].join();
    }
    return 0;
}