fork download
  1. #include <thread>
  2. #include <mutex>
  3. #include <condition_variable>
  4. #include <chrono>
  5. #include <iostream>
  6. #include <queue>
  7.  
  8. class Logger // singleton class
  9. {
  10. public:
  11. Logger() : mThread{}, mCV{}, mMutex{}, mQueue{}, mStop{ false }
  12. {
  13. mThread = std::thread(&Logger::Run, this);
  14. }
  15.  
  16. ~Logger()
  17. {
  18. if (mThread.joinable())
  19. {
  20. mThread.join();
  21. }
  22. }
  23.  
  24. static Logger& getInstance() {
  25. static Logger logger;
  26. return logger;
  27. }
  28.  
  29. void Stop()
  30. {
  31. {
  32. std::lock_guard<std::mutex> lk(mMutex);
  33. mStop = true;
  34. }
  35. mCV.notify_one();
  36. }
  37.  
  38. void WriteMessage(const std::string& msg)
  39. {
  40. {
  41. std::lock_guard<std::mutex> lk(mMutex);
  42. mQueue.push(msg);
  43. }
  44. mCV.notify_one();
  45. }
  46.  
  47. private:
  48. void Run()
  49. {
  50. while (true)
  51. {
  52. std::unique_lock<std::mutex> lock(mMutex);
  53. mCV.wait(lock, [&]() { return mStop || !mQueue.empty(); });
  54.  
  55. //Stop if needed
  56. if (mStop)
  57. {
  58. std::cout << "--- Stopping ---" << std::endl;
  59. break;
  60. }
  61.  
  62. std::string msg = std::move(mQueue.front());
  63. mQueue.pop();
  64. lock.unlock();
  65.  
  66. std::cout << msg << std::endl;
  67. }
  68. }
  69.  
  70. private:
  71. std::thread mThread;
  72. std::condition_variable mCV;
  73. std::mutex mMutex;
  74. std::queue<std::string> mQueue;
  75. bool mStop;
  76. };
  77.  
  78.  
  79. int main()
  80. {
  81. Logger& logger = Logger::getInstance();
  82.  
  83. std::thread t1([&logger, count = 10]() mutable {
  84. while (count > 0)
  85. {
  86. logger.WriteMessage("Hello from thread1");
  87. std::this_thread::sleep_for(std::chrono::milliseconds(500));
  88. --count;
  89. }
  90. });
  91.  
  92. std::thread t2([&logger, count = 20]() mutable {
  93. while (count > 0)
  94. {
  95. logger.WriteMessage(" Hello from thread2");
  96. std::this_thread::sleep_for(std::chrono::milliseconds(250));
  97. --count;
  98. }
  99. });
  100.  
  101. t1.join();
  102. t2.join();
  103. logger.Stop();
  104.  
  105. }
Success #stdin #stdout 0s 4356KB
stdin
Standard input is empty
stdout
        Hello from thread2
Hello from thread1
        Hello from thread2
Hello from thread1
        Hello from thread2
        Hello from thread2
Hello from thread1
        Hello from thread2
        Hello from thread2
Hello from thread1
        Hello from thread2
        Hello from thread2
Hello from thread1
        Hello from thread2
        Hello from thread2
Hello from thread1
        Hello from thread2
        Hello from thread2
Hello from thread1
        Hello from thread2
        Hello from thread2
Hello from thread1
        Hello from thread2
        Hello from thread2
Hello from thread1
        Hello from thread2
        Hello from thread2
Hello from thread1
        Hello from thread2
        Hello from thread2
--- Stopping ---