#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