Omnifarious icon

C++ timer priority queue

Omnifarious | PRO | 02/12/19 06:26:10 AM UTC | 0 ⭐ | 297 👁️ | Never ⏰ | []
C++ |

2.22 KB

|

None

|

0 👍

/

0 👎

#include <fmt/core.h>
#include <iostream>
#include <thread>
#include <queue>
#include <vector>
#include <condition_variable>
#include <chrono>
#include <utility>
#include <string>
#include <mutex>
 
using timed_msg_t = ::std::pair<::std::chrono::system_clock::time_point,
                                 ::std::string>;
 
class time_smaller
{
 public:
   bool operator ()(timed_msg_t const &a, timed_msg_t const &b)
   {
      return b.first < a.first;
   }
};
 
using timer_queue = ::std::priority_queue<timed_msg_t,
                                          ::std::vector<timed_msg_t>,
                                          time_smaller>;
 
using ::std::mutex;
using ::std::condition_variable;
using ::std::thread;
using ::std::unique_lock;
 
static auto const start = ::std::chrono::system_clock::now();
 
void timer_queue_thread(mutex &queue_mutex,
                        condition_variable &queue_condition,
                        timer_queue &q)
{
   unique_lock<mutex> qlock(queue_mutex);
   while (!q.empty()) {
      auto now = ::std::chrono::system_clock::now();
      auto const &top = q.top();
      if (top.first <= now) {
         double milliseconds_from_start = (now - start) / ::std::chrono::milliseconds(1);
         ::fmt::print("At time: {}ms - \"{}\"\n", milliseconds_from_start, top.second);
         q.pop();
      } else {
         queue_condition.wait_until(qlock, top.first);
      }
   }
}
 
int main()
{
   timer_queue tq;
   mutex queue_mutex;
   condition_variable queue_condition;
   {
      unique_lock<mutex> qlock(queue_mutex);
      tq.emplace(start + 60 * ::std::chrono::seconds(1), "Starting event.");
   }
   ::std::thread timer_processing{timer_queue_thread, ::std::ref(queue_mutex), ::std::ref(queue_condition), ::std::ref(tq)};
   while (true) {
      int seconds;
      ::std::string msg;
      ::std::cout << "Enter a time and message:\n";
      ::std::cin >> seconds;
      getline(::std::cin, msg);
      {
         unique_lock<mutex> qlock(queue_mutex);
         auto const qtime = ::std::chrono::system_clock::now() + seconds * ::std::chrono::seconds(1);
         tq.emplace(qtime, msg);
         queue_condition.notify_one();
      }
   }
   return 0;
}

Comments