I need to remove elements from a delay-queue in temporal order (where earlier elements have higher priority). I have a C++11 solution, but I'm wondering if there isn't a better one.
The relevant sections of code are these. (Please forgive or correct any typos.)
#include <chrono>
#include <condition_variable>
#include <mutex>
#include <queue>
...
using Clock = std::steady_clock;
using Value = ...; ///< The values stored in the delay-queue
std::mutex mutex;
std::condition_variable cond;
struct Elt {
Value value;
Clock::time_point time;
Elt(const Value& value, const Clock::time_point& time)
: value(value)
, time(time)
{}
bool operator<(const Elt& rhs) {
return time > rhs.time; // Later times have lower priority
}
}
std::priority_queue<Elt> queue; ///< The delay-queue
...
// On one thread
Clock::duration delay = ...; ///< The delay before the value should be removed
std::lock_guard guard{mutex};
queue.emplace(value, Clock::now() + delay);
cond.notify_one();
...
// On another thread
std::unique_lock lock{mutex};
if (queue.empty())
cond.wait(lock, [&]{return !queue.empty();});
auto pred = [&]{return queue.top().time >= Clock::now();};
cond.wait_until(lock, queue.top().time, pred);
auto value = queue.top().value;
queue.pop();
...
In particular, I wonder if two condition-variable calls are necessary to ensure correct behavior under all circumstances.
Is there a "better" way?
Aucun commentaire:
Enregistrer un commentaire