threadpool
parent
8d73163cc4
commit
fddef65704
|
@ -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();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue