Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <signal.h>
- #include <sys/types.h>
- #include <sys/wait.h>
- #include <chrono>
- #include <condition_variable>
- #include <ctime>
- #include <functional>
- #include <iostream>
- #include <mutex>
- #include <queue>
- #include <ratio>
- #include <thread>
- struct Task {
- std::chrono::steady_clock::time_point time;
- std::function<void()> functor;
- const bool operator<(const Task &other) const { return time > other.time; }
- };
- class Scheduler {
- public:
- Scheduler(std::function<void(std::function<void()>)> sink_);
- void Schedule(Task);
- ~Scheduler();
- private:
- void Worker();
- std::function<void(std::function<void()>)> sink;
- std::priority_queue<Task> queue;
- std::condition_variable enqueue_condition;
- std::mutex queue_lock;
- std::thread worker;
- double threshold = 0.01;
- bool enabled;
- };
- // Scheduler::Schedule(Task task) {
- // auto interval = task.time - std::chrono::steady_clock::now();
- // std::thread([this, task](){ std::this_thread::sleep_for(task.time -
- // std::chrono::steady_clock::now());
- // task.functor();}).detach();
- //}
- Scheduler::~Scheduler() {
- enabled = false;
- worker.join();
- }
- void Scheduler::Worker() {
- auto time_point = std::chrono::steady_clock::now();
- for (;;) {
- std::unique_lock<std::mutex> guard(queue_lock);
- enqueue_condition.wait_until(
- guard, time_point, [this]() { return !queue.empty() || !enabled; });
- if (!enabled && queue.empty()) return;
- if (queue.empty()) {
- guard.unlock();
- continue;
- }
- std::chrono::duration<double, std::milli> remained =
- queue.top().time - std::chrono::steady_clock::now();
- if (remained.count() <= threshold) {
- sink(std::move(queue.top().functor));
- queue.pop();
- guard.unlock();
- continue;
- }
- time_point = queue.top().time;
- guard.unlock();
- }
- }
- Scheduler::Scheduler(std::function<void(std::function<void()>)> sink)
- : sink(sink) {
- worker = std::thread(&Scheduler::Worker, this);
- }
- void Scheduler::Schedule(Task task) {
- std::unique_lock<std::mutex> guard(queue_lock);
- queue.emplace(task);
- }
- int main() {
- using namespace std::literals::chrono_literals;
- Scheduler scheduler([](std::function<void()> handler) { handler(); });
- scheduler.Schedule({std::chrono::steady_clock::now() + 1000ms,
- []() { printf("first time\n"); }});
- scheduler.Schedule({std::chrono::steady_clock::now() + 10000ms,
- []() { printf("second time\n"); }});
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement