Advertisement
Omnifarious

C++ timer priority queue

Feb 12th, 2019
141
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.22 KB | None | 0 0
  1. #include <fmt/core.h>
  2. #include <iostream>
  3. #include <thread>
  4. #include <queue>
  5. #include <vector>
  6. #include <condition_variable>
  7. #include <chrono>
  8. #include <utility>
  9. #include <string>
  10. #include <mutex>
  11.  
  12. using timed_msg_t = ::std::pair<::std::chrono::system_clock::time_point,
  13.                                  ::std::string>;
  14.  
  15. class time_smaller
  16. {
  17.  public:
  18.    bool operator ()(timed_msg_t const &a, timed_msg_t const &b)
  19.    {
  20.       return b.first < a.first;
  21.    }
  22. };
  23.  
  24. using timer_queue = ::std::priority_queue<timed_msg_t,
  25.                                           ::std::vector<timed_msg_t>,
  26.                                           time_smaller>;
  27.  
  28. using ::std::mutex;
  29. using ::std::condition_variable;
  30. using ::std::thread;
  31. using ::std::unique_lock;
  32.  
  33. static auto const start = ::std::chrono::system_clock::now();
  34.  
  35. void timer_queue_thread(mutex &queue_mutex,
  36.                         condition_variable &queue_condition,
  37.                         timer_queue &q)
  38. {
  39.    unique_lock<mutex> qlock(queue_mutex);
  40.    while (!q.empty()) {
  41.       auto now = ::std::chrono::system_clock::now();
  42.       auto const &top = q.top();
  43.       if (top.first <= now) {
  44.          double milliseconds_from_start = (now - start) / ::std::chrono::milliseconds(1);
  45.          ::fmt::print("At time: {}ms - \"{}\"\n", milliseconds_from_start, top.second);
  46.          q.pop();
  47.       } else {
  48.          queue_condition.wait_until(qlock, top.first);
  49.       }
  50.    }
  51. }
  52.  
  53. int main()
  54. {
  55.    timer_queue tq;
  56.    mutex queue_mutex;
  57.    condition_variable queue_condition;
  58.    {
  59.       unique_lock<mutex> qlock(queue_mutex);
  60.       tq.emplace(start + 60 * ::std::chrono::seconds(1), "Starting event.");
  61.    }
  62.    ::std::thread timer_processing{timer_queue_thread, ::std::ref(queue_mutex), ::std::ref(queue_condition), ::std::ref(tq)};
  63.    while (true) {
  64.       int seconds;
  65.       ::std::string msg;
  66.       ::std::cout << "Enter a time and message:\n";
  67.       ::std::cin >> seconds;
  68.       getline(::std::cin, msg);
  69.       {
  70.          unique_lock<mutex> qlock(queue_mutex);
  71.          auto const qtime = ::std::chrono::system_clock::now() + seconds * ::std::chrono::seconds(1);
  72.          tq.emplace(qtime, msg);
  73.          queue_condition.notify_one();
  74.       }
  75.    }
  76.    return 0;
  77. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement