threadpool

main
Brett 2023-04-22 21:11:30 -04:00
parent 8d73163cc4
commit fddef65704
2 changed files with 106 additions and 3 deletions

View File

@ -9,13 +9,44 @@
#include <thread> #include <thread>
#include <mutex> #include <mutex>
#include <functional>
#include <queue>
namespace blt { namespace blt {
class runnable {
public:
virtual void run() = 0;
virtual ~runnable() = default;
};
/**
* If your runnable functions are small consider using another data structure,
* as thread_pool will be slow if many small tasks are needed to be ran.
* thread_pool is designed for running large long run tasks
*/
class thread_pool { class thread_pool {
private: private:
volatile bool halted;
int MAX_THREADS;
std::queue<runnable*> runQueue {};
std::vector<std::thread*> threads {};
std::mutex queueMutex {};
public: public:
explicit thread_pool(int maxThreads);
/**
* Attempts to start the thread_pool.
*/
void start();
void run(std::function<void()>& func);
void run(runnable* func);
void stop();
~thread_pool();
}; };
} }

View File

@ -4,3 +4,75 @@
* See LICENSE file for license detail * See LICENSE file for license detail
*/ */
#include <util/threadpool.h> #include <util/threadpool.h>
class runnable_function : public blt::runnable {
private:
std::function<void()>& func;
public:
explicit runnable_function(std::function<void()>& func): func(func) {}
void run() final {
func();
}
};
blt::thread_pool::thread_pool(int maxThreads): MAX_THREADS(maxThreads) {
halted = false;
}
blt::thread_pool::~thread_pool() {
stop();
}
void blt::thread_pool::start() {
for (int i = 0; i < MAX_THREADS; i++) {
threads.push_back(
new std::thread(
[this]() -> void {
while (!halted){
// acquire a resource from the runnable queue
std::unique_lock<std::mutex> lock(queueMutex);
runnable* run = runQueue.front();
runQueue.pop();
lock.unlock();
// attempt to run the function
run->run();
delete(run);
}
}
));
}
}
void blt::thread_pool::stop() {
if (halted)
return;
halted = true;
for (std::thread* thread : threads)
thread->join();
for (std::thread* thread : threads)
delete thread;
std::scoped_lock<std::mutex> lock(queueMutex);
while (!runQueue.empty()){
delete runQueue.front();
runQueue.pop();
}
}
void blt::thread_pool::run(std::function<void()>& func) {
std::scoped_lock<std::mutex> lock(queueMutex);
runQueue.push(new runnable_function(func));
}
void blt::thread_pool::run(blt::runnable* func) {
std::scoped_lock<std::mutex> lock(queueMutex);
runQueue.push(func)
}