Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <stdio.h>
- #include <thread>
- #include <vector>
- #include <queue>
- #include <mutex>
- #include <chrono>
- #include <condition_variable>
- #include <random>
- namespace
- {
- std::mutex mut, iomutex;
- std::condition_variable cv;
- std::random_device rd;
- std::mt19937 re(rd());
- std::uniform_int_distribution<int> ui(1, 500);
- }
- template<typename T>
- class Buffer
- {
- public:
- Buffer<T>(unsigned int size)
- : m_size { size } { }
- void enqueue(const T& item)
- {
- std::unique_lock<std::mutex> lk(mut);
- cv.wait(lk, [&] { return m_size > m_buffer.size(); });
- m_buffer.push(item);
- lk.unlock();
- cv.notify_all();
- std::this_thread::sleep_for(std::chrono::milliseconds(500));
- }
- void dequeue(T& item)
- {
- std::unique_lock<std::mutex> lk(mut);
- cv.wait(lk, [&] { return !m_buffer.empty(); });
- item = m_buffer.front();
- m_buffer.pop();
- lk.unlock();
- cv.notify_all();
- std::this_thread::sleep_for(std::chrono::milliseconds(500));
- }
- private:
- std::queue<T> m_buffer;
- unsigned int m_size;
- };
- class Producer
- {
- public:
- Producer(Buffer<int>& buffer)
- : m_buffer { buffer }
- { }
- Producer& operator = (const Producer&) = delete;
- ~Producer() = default;
- void run()
- {
- while (true)
- {
- int item = ui(re);
- m_buffer.enqueue(item);
- std::lock_guard<std::mutex> lk(iomutex);
- std::cout << std::this_thread::get_id() << "\t produced " << item << std::endl;
- }
- }
- private:
- Buffer<int>& m_buffer;
- };
- class Consumer
- {
- public:
- Consumer(Buffer<int>& buffer)
- : m_buffer { buffer }
- { }
- Consumer& operator = (const Consumer&) = delete;
- ~Consumer() = default;
- void run()
- {
- while (true)
- {
- int item;
- m_buffer.dequeue(item);
- std::lock_guard<std::mutex> lk(iomutex);
- std::cout << std::this_thread::get_id() << "\t consumed " << item << std::endl;
- }
- }
- private:
- Buffer<int>& m_buffer;
- };
- int main()
- {
- Buffer<int> buffer { 10 };
- std::vector<std::thread> producers;
- std::vector<std::thread> consumers;
- for (auto i = 0; i < 6; ++i)
- {
- Producer p { buffer };
- Consumer c { buffer };
- producers.emplace_back(&Producer::run, &p);
- consumers.emplace_back(&Consumer::run, &c);
- }
- for (auto& p : producers) p.join();
- for (auto& c : consumers) c.join();
- getchar();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement