Advertisement
Guest User

Untitled

a guest
Jan 19th, 2016
137
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.64 KB | None | 0 0
  1. #include <iostream>
  2. #include <stdio.h>
  3. #include <thread>
  4. #include <vector>
  5. #include <queue>
  6. #include <mutex>
  7. #include <chrono>
  8. #include <condition_variable>
  9. #include <random>
  10.  
  11. namespace
  12. {
  13. std::mutex mut, iomutex;
  14. std::condition_variable cv;
  15.  
  16. std::random_device rd;
  17. std::mt19937 re(rd());
  18. std::uniform_int_distribution<int> ui(1, 500);
  19. }
  20.  
  21. template<typename T>
  22. class Buffer
  23. {
  24. public:
  25.     Buffer<T>(unsigned int size)
  26.         : m_size { size } { }
  27.    
  28.     void enqueue(const T& item)
  29.     {
  30.         std::unique_lock<std::mutex> lk(mut);
  31.         cv.wait(lk, [&] { return m_size > m_buffer.size(); });
  32.         m_buffer.push(item);
  33.         lk.unlock();
  34.         cv.notify_all();
  35.         std::this_thread::sleep_for(std::chrono::milliseconds(500));
  36.     }
  37.  
  38.     void dequeue(T& item)
  39.     {
  40.         std::unique_lock<std::mutex> lk(mut);
  41.         cv.wait(lk, [&] { return !m_buffer.empty(); });
  42.         item = m_buffer.front();
  43.         m_buffer.pop();
  44.         lk.unlock();
  45.         cv.notify_all();
  46.         std::this_thread::sleep_for(std::chrono::milliseconds(500));
  47.     }
  48.  
  49. private:
  50.     std::queue<T> m_buffer;
  51.     unsigned int m_size;
  52. };
  53.  
  54. class Producer
  55. {
  56. public:
  57.     Producer(Buffer<int>& buffer)
  58.         : m_buffer { buffer }
  59.     { }
  60.  
  61.     Producer& operator = (const Producer&) = delete;
  62.     ~Producer() = default;
  63.  
  64.     void run()
  65.     {
  66.         while (true)
  67.         {
  68.             int item = ui(re);
  69.             m_buffer.enqueue(item);
  70.             std::lock_guard<std::mutex> lk(iomutex);
  71.             std::cout << std::this_thread::get_id() << "\t produced " << item << std::endl;
  72.         }
  73.     }
  74.  
  75. private:
  76.     Buffer<int>& m_buffer;
  77. };
  78.  
  79. class Consumer
  80. {
  81. public:
  82.     Consumer(Buffer<int>& buffer)
  83.         : m_buffer { buffer }
  84.     { }
  85.  
  86.     Consumer& operator = (const Consumer&) = delete;
  87.     ~Consumer() = default;
  88.  
  89.     void run()
  90.     {
  91.         while (true)
  92.         {
  93.             int item;
  94.             m_buffer.dequeue(item);
  95.             std::lock_guard<std::mutex> lk(iomutex);
  96.             std::cout << std::this_thread::get_id() << "\t consumed " << item << std::endl;
  97.         }
  98.     }
  99.  
  100. private:
  101.     Buffer<int>& m_buffer;
  102. };
  103.  
  104. int main()
  105. {
  106.     Buffer<int> buffer { 10 };
  107.     std::vector<std::thread> producers;
  108.     std::vector<std::thread> consumers;
  109.  
  110.     for (auto i = 0; i < 6; ++i)
  111.     {
  112.         Producer p { buffer };
  113.         Consumer c { buffer };
  114.  
  115.         producers.emplace_back(&Producer::run, &p);
  116.         consumers.emplace_back(&Consumer::run, &c);
  117.     }
  118.    
  119.     for (auto& p : producers) p.join();
  120.     for (auto& c : consumers) c.join();
  121.  
  122.     getchar();
  123.  
  124.     return 0;
  125. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement