fork download
  1. #include <iostream>
  2. #include <thread>
  3. #include <vector>
  4. #include <mutex>
  5. #include <chrono>
  6. #include <queue>
  7.  
  8. class LockedQueue {
  9. std::queue<int> queue_;
  10. mutable std::mutex mutex_;
  11. public:
  12. LockedQueue() = default;
  13.  
  14. // these don't have to be deleted, but you'd have to decide whether or
  15. // not each operation needed to invoke a lock, and in the case of operator=
  16. // you have two mutexes to contend with.
  17. LockedQueue(const LockedQueue&) = delete;
  18. LockedQueue(LockedQueue&&) = delete;
  19. LockedQueue& operator=(const LockedQueue&) = delete;
  20. LockedQueue& operator=(LockedQueue&&) = delete;
  21.  
  22. void push(int value) {
  23. std::lock_guard<std::mutex> lock(mutex_);
  24. queue_.push(value);
  25. }
  26. int pop() {
  27. std::lock_guard<std::mutex> lock(mutex_);
  28. int value = queue_.front();
  29. queue_.pop();
  30. return value;
  31. }
  32. bool empty() const {
  33. std::lock_guard<std::mutex> lock(mutex_);
  34. return queue_.empty();
  35. }
  36. };
  37.  
  38. void func(LockedQueue& work, LockedQueue& results);
  39.  
  40. int main()
  41. {
  42. LockedQueue work, results;
  43. std::vector<std::thread> threads;
  44.  
  45. for (int i = 0; i < 4; i++)
  46. {
  47. work.push(i);
  48. threads.emplace_back(func, std::ref(work), std::ref(results));
  49. }
  50.  
  51. for (auto& thread : threads)
  52. thread.join();
  53.  
  54. while (!results.empty()) {
  55. int i = results.pop();
  56. std::cout << i;
  57. }
  58. }
  59.  
  60. void func(LockedQueue& work, LockedQueue& results)
  61. {
  62. int index = work.pop();
  63. using namespace std::chrono_literals;
  64. std::this_thread::sleep_for(1s);
  65. results.push(index);
  66. }
Success #stdin #stdout 0s 36248KB
stdin
Standard input is empty
stdout
0123