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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章