fork(3) download
  1. #include <atomic>
  2. #include <condition_variable>
  3. #include <iostream>
  4. #include <mutex>
  5. #include <queue>
  6. #include <string>
  7. #include <thread>
  8.  
  9. template <typename T>
  10. class ThreadSafeQueue
  11. {
  12. public:
  13. ThreadSafeQueue() { }
  14. ~ThreadSafeQueue() { }
  15.  
  16. bool
  17. empty()
  18. {
  19. return(_queue.empty());
  20. }
  21.  
  22. T
  23. pop()
  24. {
  25. std::unique_lock<std::mutex> mlock(_mutex);
  26. while (_queue.empty())
  27. {
  28. _cond.wait(mlock);
  29. }
  30.  
  31. auto item = _queue.front();
  32. _queue.pop();
  33.  
  34. return(item);
  35. }
  36.  
  37. void
  38. pop(T& item)
  39. {
  40. std::unique_lock<std::mutex> mlock(_mutex);
  41.  
  42. while (_queue.empty())
  43. {
  44. _cond.wait(mlock);
  45. }
  46.  
  47. item = _queue.front();
  48. _queue.pop();
  49. }
  50.  
  51. void
  52. push(const T& item)
  53. {
  54. std::unique_lock<std::mutex> mlock(_mutex);
  55.  
  56. _queue.push(item);
  57. mlock.unlock();
  58. _cond.notify_one();
  59. }
  60.  
  61. void
  62. push(T&& item)
  63. {
  64. std::unique_lock<std::mutex> mlock(_mutex);
  65. _queue.push(std::move(item));
  66. mlock.unlock();
  67. _cond.notify_one();
  68. }
  69.  
  70. private:
  71. std::queue<T> _queue;
  72. std::mutex _mutex;
  73. std::condition_variable _cond;
  74. };
  75.  
  76. int main() {
  77. ThreadSafeQueue<std::string> q;
  78. const int TOTAL = 100000;
  79. const int N = 10; // must evenly divide TOTAL
  80.  
  81. std::atomic<int> count;
  82. std::vector<std::thread> poppers;
  83.  
  84. for (int i = 0; i < N; ++i)
  85. poppers.emplace_back([&]{ for(int i = 0; i < TOTAL / N; ++i) if (q.pop() == "foo") ++count; });
  86.  
  87. std::thread pusher([&]{ for(int i = 0; i < TOTAL; ++i) q.push("foo"); });
  88.  
  89. pusher.join();
  90. for (auto& popper : poppers)
  91. popper.join();
  92.  
  93. std::cout << "Queue is " << (q.empty() ? "" : "NOT ") << "empty" << std::endl;
  94. std::cout << "Number of elements pushed = " << TOTAL << std::endl;
  95. std::cout << "Number of elements popped = " << count << std::endl;
  96.  
  97. return 0;
  98. }
Success #stdin #stdout 0.01s 7188KB
stdin
Standard input is empty
stdout
Queue is empty
Number of elements pushed = 100000
Number of elements popped = 111007