فهرست منبع

Replaced multimap with priority_queue

Paul-Louis Ageneau 4 سال پیش
والد
کامیت
5d0c62e4bc
2فایلهای تغییر یافته به همراه16 افزوده شده و 9 حذف شده
  1. 5 6
      src/threadpool.cpp
  2. 11 3
      src/threadpool.hpp

+ 5 - 6
src/threadpool.cpp

@@ -68,17 +68,16 @@ std::function<void()> ThreadPool::dequeue() {
 	std::unique_lock lock(mMutex);
 	while (true) {
 		if (!mTasks.empty()) {
-			clock::time_point time = mTasks.begin()->first;
-			if (time <= clock::now()) {
-				auto task = std::move(mTasks.begin()->second);
-				mTasks.erase(mTasks.begin());
-				return task;
+			if (mTasks.top().time <= clock::now()) {
+				auto func = std::move(mTasks.top().func);
+				mTasks.pop();
+				return func;
 			}
 
 			if (mJoining)
 				break;
 
-			mCondition.wait_until(lock, time);
+			mCondition.wait_until(lock, mTasks.top().time);
 		} else {
 			if (mJoining)
 				break;

+ 11 - 3
src/threadpool.hpp

@@ -24,11 +24,12 @@
 
 #include <chrono>
 #include <condition_variable>
+#include <deque>
 #include <functional>
 #include <future>
-#include <map>
 #include <memory>
 #include <mutex>
+#include <queue>
 #include <stdexcept>
 #include <thread>
 #include <vector>
@@ -71,9 +72,16 @@ protected:
 	std::function<void()> dequeue(); // returns null function if joining
 
 	std::vector<std::thread> mWorkers;
-	std::multimap<clock::time_point, std::function<void()>> mTasks;
 	std::atomic<bool> mJoining = false;
 
+	struct Task {
+		clock::time_point time;
+		std::function<void()> func;
+		bool operator>(const Task &other) const { return time > other.time; }
+		bool operator<(const Task &other) const { return time < other.time; }
+	};
+	std::priority_queue<Task, std::deque<Task>, std::greater<Task>> mTasks;
+
 	mutable std::mutex mMutex, mWorkersMutex;
 	std::condition_variable mCondition;
 };
@@ -105,7 +113,7 @@ auto ThreadPool::schedule(clock::time_point time, F &&f, Args &&...args)
 	});
 	std::future<R> result = task->get_future();
 
-	mTasks.emplace(time, [task = std::move(task), token = Init::Token()]() { return (*task)(); });
+	mTasks.push({time, [task = std::move(task), token = Init::Token()]() { return (*task)(); }});
 	mCondition.notify_one();
 	return result;
 }