Chris_M_Thomasson

Simple C++ Deque Single Producer / Multiple Consumer Example

Mar 19th, 2017
328
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.05 KB | None | 0 0
  1. #include <cstdio>
  2. #include <deque>
  3. #include <condition_variable>
  4. #include <mutex>
  5. #include <memory>
  6. #include <thread>
  7. #include <algorithm>
  8. #include <cassert>
  9.  
  10.  
  11. template<typename T>
  12. struct queue
  13. {
  14.     typedef std::deque<T> raw_queue_t;
  15.  
  16.     raw_queue_t m_queue;
  17.     std::condition_variable m_cond;
  18.     std::mutex m_mutex;
  19.  
  20.     void push(T const& obj)
  21.     {
  22.         {
  23.             std::unique_lock<std::mutex> lock(m_mutex);
  24.             m_queue.push_back(obj);
  25.         }
  26.  
  27.         m_cond.notify_one();
  28.     }
  29.  
  30.     T pop()
  31.     {
  32.         T front;
  33.  
  34.         {
  35.             std::unique_lock<std::mutex> lock(m_mutex);
  36.             while (! m_queue.size()) m_cond.wait(lock);
  37.             front = m_queue.front();
  38.             m_queue.pop_front();
  39.         }
  40.  
  41.         return front;
  42.     }
  43. };
  44.  
  45.  
  46. typedef queue<unsigned int> string_queue_t;
  47. #define CONSUMERS 5
  48. #define N 1000
  49.  
  50.  
  51. void producer(std::mutex& std_out_mtx, string_queue_t& queue)
  52. {
  53.     {
  54.         std::unique_lock<std::mutex> lock(std_out_mtx);
  55.         std::printf("producer::queue::(%p) - enter\n", (void*)&queue);
  56.     }
  57.  
  58.     for (unsigned int i = 0; i < N; ++i)
  59.     {
  60.         queue.push(i + 1);
  61.         std::this_thread::yield(); // just for some spice
  62.     }
  63.  
  64.     for (unsigned int i = 0; i < CONSUMERS; ++i)
  65.     {
  66.         queue.push(0);
  67.         std::this_thread::yield(); // just for some spice
  68.     }
  69.  
  70.     {
  71.         std::unique_lock<std::mutex> lock(std_out_mtx);
  72.         std::printf("producer::queue::(%p) - exit\n", (void*)&queue);
  73.     }
  74. }
  75.  
  76.  
  77. void consumer(unsigned int id, std::mutex& std_out_mtx, string_queue_t& queue)
  78. {
  79.     {
  80.         std::unique_lock<std::mutex> lock(std_out_mtx);
  81.         std::printf("consumer(%u)::queue::(%p) - enter\n", id, (void*)&queue);
  82.     }
  83.  
  84.     unsigned int prev = 0;
  85.  
  86.     for (;;)
  87.     {
  88.         unsigned int msg = queue.pop();
  89.  
  90.         {
  91.             std::unique_lock<std::mutex> lock(std_out_mtx);
  92.             std::printf("consumer(%u)::msg::(%u)\n", id, msg);
  93.         }
  94.  
  95.         if (msg == 0) break;
  96.  
  97.         assert(msg > prev); // validate fifo nature
  98.  
  99.         prev = msg;
  100.     }
  101.  
  102.     {
  103.         std::unique_lock<std::mutex> lock(std_out_mtx);
  104.         std::printf("consumer::queue::(%p) - exit\n", (void*)&queue);
  105.     }
  106. }
  107.  
  108.  
  109. int main(void)
  110. {
  111.     {
  112.         string_queue_t queue;
  113.         std::mutex std_out_mutex;
  114.  
  115.         std::thread consumers[CONSUMERS];
  116.  
  117.         for (unsigned int i = 0; i < CONSUMERS; ++i)
  118.         {
  119.             consumers[i] = std::thread(
  120.                 consumer,
  121.                 i,
  122.                 std::ref(std_out_mutex),
  123.                 std::ref(queue)
  124.             );
  125.         }
  126.  
  127.         std::thread producer_thread(
  128.             producer,
  129.             std::ref(std_out_mutex),
  130.             std::ref(queue)
  131.         );
  132.  
  133.         producer_thread.join();
  134.  
  135.         for (unsigned int i = 0; i < CONSUMERS; ++i)
  136.         {
  137.             consumers[i].join();
  138.         }
  139.     }
  140.  
  141.     std::printf("\nComplete, hit <ENTER> to exit...\n");
  142.     std::fflush(stdout);
  143.     std::getchar();
  144.  
  145.     return 0;
  146. }
Advertisement
Add Comment
Please, Sign In to add comment