LightPool is a lightweight thread and pooling system originally made for loading and parsing data.
Open LightPool.sln solution using Visual Studio (recommended version 2019) or Rider
First of all you need to instanciate a pool the following way.
#include "Includes/LightPool.hpp"
using namespace Light;
LightPool pool;
To register thread, this very simple, you can either do a for loop or register it by hand dependin on your needs.
MAX_THREADS in our case should be equals or less than what your current system can handle for safety reasons.
for (int i = 0; i < MAX_THREAD; i++) {
pool.registerThread(new LightThread(pool, std::to_string(i)));
}
To register a task, same as before, the method is self explanatory.
MAX_TASKS in our case can be equal to anything, this is an exemple you don't necessarily need to use a for loop.
To register a Task, use a lambda so you can register any functions with args or not.
Two simple functions registered here that will print on the console some text.
We make the thread sleep for 1 ms, but not necessary at all.
for (int i = 0; i < MAX_TASKS; i++) {
if (i % 2) {
pool.registerTask(Task { []() { sayGoodbye(); }});
} else {
pool.registerTask(Task{ []() { sayHello(); } });
}
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
As an example, since the lib is not supposed to be used all alone, it will keep the program running.
Itc an be replaced by an if condition to check if the pool is empty or not and decide what do to base on the result.
while (!pool.getTasks().empty());
To shutdown the pool, very simple, call the stop() method.
This will tell the thread(s) to finish their current task and then will delete them.
Note that once the stop() method was called, even if there are remaining tasks waiting to be processed in queued, they will be ignored for obvious reasons, make sure you call it at the right place.
pool.stop();
The Task object is a simple structure holding a std::function than returns void, it might be restrictive but usually you don't need to return values when doing multithreaded apps, the response can be bottled in the registered function itself.
struct Task
{
std::function<void()> task;
};
The LightMutex is a very user friendly implementation of the std::mutex, but with a tighter range of utility. Regarding the lightweight aspect, you cannot do better.
class LightMutex
{
public:
void lock();
void unlock();
private:
std::atomic<bool> locked{ false };
};
void LightMutex::lock() {
while (locked.exchange(true, std::memory_order_relaxed));
std::atomic_thread_fence(std::memory_order_acquire);
}
void LightMutex::unlock() {
std::atomic_thread_fence(std::memory_order_release);
locked.store(false, std::memory_order_relaxed);
}
You can head to the following folder to have a better view of the whole library in action.
-> .cpp files located in sources/
-> .hpp files located in Includes/
Exemple file is located in samples/ named "MainSample.cpp" (no header file for this one)
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
Please make sure to update tests as appropriate.