Advertisement
Guest User

Untitled

a guest
Nov 13th, 2019
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.53 KB | None | 0 0
  1. #include <signal.h>
  2. #include <sys/types.h>
  3. #include <sys/wait.h>
  4. #include <chrono>
  5. #include <condition_variable>
  6. #include <ctime>
  7. #include <functional>
  8. #include <iostream>
  9. #include <mutex>
  10. #include <queue>
  11. #include <ratio>
  12. #include <thread>
  13.  
  14. struct Task {
  15. std::chrono::steady_clock::time_point time;
  16. std::function<void()> functor;
  17. const bool operator<(const Task &other) const { return time > other.time; }
  18. };
  19.  
  20. class Scheduler {
  21. public:
  22. Scheduler(std::function<void(std::function<void()>)> sink_);
  23. void Schedule(Task);
  24. ~Scheduler();
  25.  
  26. private:
  27. void Worker();
  28. std::function<void(std::function<void()>)> sink;
  29. std::priority_queue<Task> queue;
  30. std::condition_variable enqueue_condition;
  31. std::mutex queue_lock;
  32. std::thread worker;
  33. double threshold = 0.01;
  34. bool enabled;
  35. };
  36.  
  37. // Scheduler::Schedule(Task task) {
  38. // auto interval = task.time - std::chrono::steady_clock::now();
  39. // std::thread([this, task](){ std::this_thread::sleep_for(task.time -
  40. // std::chrono::steady_clock::now());
  41. // task.functor();}).detach();
  42. //}
  43.  
  44. Scheduler::~Scheduler() {
  45. enabled = false;
  46. worker.join();
  47. }
  48.  
  49. void Scheduler::Worker() {
  50. auto time_point = std::chrono::steady_clock::now();
  51. for (;;) {
  52. std::unique_lock<std::mutex> guard(queue_lock);
  53. enqueue_condition.wait_until(
  54. guard, time_point, [this]() { return !queue.empty() || !enabled; });
  55.  
  56. if (!enabled && queue.empty()) return;
  57.  
  58. if (queue.empty()) {
  59. guard.unlock();
  60. continue;
  61. }
  62.  
  63. std::chrono::duration<double, std::milli> remained =
  64. queue.top().time - std::chrono::steady_clock::now();
  65. if (remained.count() <= threshold) {
  66. sink(std::move(queue.top().functor));
  67. queue.pop();
  68. guard.unlock();
  69. continue;
  70. }
  71. time_point = queue.top().time;
  72. guard.unlock();
  73. }
  74. }
  75.  
  76. Scheduler::Scheduler(std::function<void(std::function<void()>)> sink)
  77. : sink(sink) {
  78. worker = std::thread(&Scheduler::Worker, this);
  79. }
  80.  
  81. void Scheduler::Schedule(Task task) {
  82. std::unique_lock<std::mutex> guard(queue_lock);
  83. queue.emplace(task);
  84. }
  85.  
  86. int main() {
  87. using namespace std::literals::chrono_literals;
  88. Scheduler scheduler([](std::function<void()> handler) { handler(); });
  89. scheduler.Schedule({std::chrono::steady_clock::now() + 1000ms,
  90. []() { printf("first time\n"); }});
  91. scheduler.Schedule({std::chrono::steady_clock::now() + 10000ms,
  92. []() { printf("second time\n"); }});
  93. return 0;
  94. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement