#include #include #include #include #include #include #include #include #include #include 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, 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 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 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 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; }