Advertisement
TimSenin

Untitled

Nov 25th, 2022
120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.32 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include <mutex>
  4. #include <condition_variable>
  5. #include <chrono>
  6. #include <map>
  7.  
  8. template <class T>
  9. class TimerQueue {
  10. public:
  11.     using Clock = std::chrono::system_clock;
  12.     using TimePoint = Clock::time_point;
  13.  
  14. public:
  15.     void Add(const T& item, TimePoint at) {
  16.         std::unique_lock<std::mutex> lock(mtx_);  // Останавливается здесь
  17.         data_.insert({item, at});
  18.     }
  19.  
  20.     T Pop() {
  21.         std::unique_lock<std::mutex> lock(mtx_);
  22.         TimePoint wait_time = data_.begin()->second;
  23.         T value = data_.begin()->first;
  24.         for (auto& [k, v] : data_) {
  25.             if (v < wait_time) {
  26.                 wait_time = std::min(wait_time, v);
  27.                 value = k;
  28.             }
  29.         }
  30.  
  31.         data_.erase(data_.find(value));
  32.         cv_.wait_until(lock, wait_time);
  33.         return value;
  34.     }
  35.  
  36. private:
  37.     std::multimap<T, TimePoint> data_;
  38.     std::condition_variable cv_;
  39.     std::mutex mtx_;
  40. };
  41.  
  42.  
  43.  
  44.  
  45. // Тест
  46. TEST(TimerQueue, TwoThreads) {
  47.     auto now = Now();
  48.  
  49.     TimerQueue<int> queue;
  50.  
  51.     std::atomic<bool> finished = false;
  52.     std::thread worker([&] {
  53.         queue.Pop();
  54.         finished = true;
  55.     });
  56.  
  57.     std::this_thread::sleep_for(500ms);
  58.     EXPECT_FALSE(finished);
  59.  
  60.     queue.Add(0, now);
  61.     worker.join();
  62. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement