simple cpp pool to limit the amount of thread running currently
simple cpp pool to limit the amount of thread running currently to make the computer more responsive.
short story
- wrapping the target function with lambda function.
- condition variable to block the wrapping function, limiting running thread amount.
long story
#include <iostream>
#include <mutex>
#include <thread>
#include <vector>
#include <string>
#include <chrono>
#include <cstdlib>
using namespace std;
class ThreadPoolAA
{
public:
mutex mtx;
mutex mtxCounter;
condition_variable condV;
int runingThreadN = 0;
int runingThreadMax = 16;
vector<thread> thds;
ThreadPoolAA(int N)
{
runingThreadMax = N;
}
template<typename Fn, typename ...Args>
int add(Fn fx, Args... argx)
{
//Lambda expressions (since C++11) - cppreference.com
//https://en.cppreference.com/w/cpp/language/lambda
//& (implicitly capture the used automatic variables by reference) and
//= (implicitly capture the used automatic variables by copy).
//The current object (*this) can be implicitly captured if either capture default is present.
//If implicitly captured, it is always captured by reference, even if the capture default is =
thds.push_back(thread([=, this]() {
{
unique_lock<mutex> lck(mtx);
//cout << "free" << endl;
condV.wait(lck, [this]() {return runingThreadN < runingThreadMax; });
lock_guard<mutex> lckCounter(mtxCounter);
runingThreadN++;
}
//cout << "runing thread n = " << runingThreadN << endl;
this_thread::sleep_for(chrono::milliseconds(500));
fx(argx...);
{
lock_guard<mutex> lckCounter(mtxCounter);
runingThreadN--;
//cout << "runing thread bb n = " << runingThreadN << endl;
condV.notify_one();
}
}));
//cout << "thread created." << endl;
return 0;
}
int join()
{
for (int idx = 0; idx < thds.size(); idx++)
{
thds[idx].join();
cout << "joined " << idx << endl;
}
return 0;
}
};
int fnc0(string aa)
{
this_thread::sleep_for(chrono::milliseconds(rand() % 1000));
cout << "fnc0 " << aa << endl;
return 0;
}
int fnc1(string aa, string ab)
{
this_thread::sleep_for(chrono::milliseconds(rand() % 1000));
cout << "fnc1 " << aa << ab << endl;
return 0;
}
int main()
{
fnc0("aa");
fnc1("ba", "bb");
cout << "================================" << endl;
ThreadPoolAA poolAA(4);
for (int idx = 0; idx < 11; idx++)
{
poolAA.add(fnc0, "ea");
poolAA.add(fnc1, "fa", "fb");
}
poolAA.join();
cout << "all done." << endl;
return 0;
}
//ref
//vit-vit/CTPL: Modern and efficient C++ Thread Pool Library
//https://github.com/vit-vit/CTPL
//Lambda expressions (since C++11) - cppreference.com
//https://en.cppreference.com/w/cpp/language/lambda#Lambda_capture
//c++ - Understanding the dots in variadic template function - Stack Overflow
//https://stackoverflow.com/questions/23485643/understanding-the-dots-in-variadic-template-function