Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Thread Pool C++

I have the following for loop:

for (int i = 0; i < 100; i++) {
    someJob();
}

I want to run this function only with 5 threads, how can I do it?
I can't use any external library.

What I've tried is to make an array with 5 threads and if the index is equal to 5 to wait all threads and do it again, but I'm sure there is another way to do that:

std::thread t[THREAD_COUNT];
int j=0;

for (int i = 0; i < 100; i++) {
    t[j++] = std::thread(someJob);
    if (j == THREAD_COUNT)
    {
        for (int k = 0; k < THREAD_COUNT; k++)
        {
            if (t[k].joinable())
                t[k].join();
        }
        j = 0;
    }
}

Any suggestion? (I can't use boost)

Thanks!

like image 998
JustASK Avatar asked Aug 11 '17 09:08

JustASK


People also ask

What is a thread pool C?

Definition of C++ Thread Pool. Threadpool in C++ is basically a pool having a fixed number of threads used when we want to work multiple tasks together (run multiple threads concurrently).

What is thread pool in C sharp?

Thread pool in C# is a collection of threads. It is used to perform tasks in the background. When a thread completes a task, it is sent to the queue wherein all the waiting threads are present. This is done so that it can be reused.

What is thread pool for?

A thread pool helps mitigate the issue of performance by reducing the number of threads needed and managing their lifecycle. Essentially, threads are kept in the thread pool until they're needed, after which they execute the task and return the pool to be reused later.


3 Answers

You could make a function that tests your thread array to find a vacant thread to run each successive job on. Something like this:

// synchronized output to prevent interleaving of results
#define sync_out(m) do{std::ostringstream o; o << m << '\n'; std::cout << o.str();}while(0)

void someJob(int id)
{
    sync_out("thread: " << id);
}

template<typename Job>
void start_thread(std::vector<std::thread>& threads, Job&& job)
{
    // find an ended thread
    for(auto&& thread: threads)
    {
        if(thread.joinable()) // still running or waiting to join
            continue;

        thread = std::thread(job);
        return;
    }

    // if not wait for one
    for(auto&& thread: threads)
    {
        if(!thread.joinable()) // dead thread (not run or already joined)
            continue;

        thread.join();
        thread = std::thread(job);
        return;
    }
}

int main()
{

    std::vector<std::thread> threads(5); // 5 threads

    for(int i = 0; i < 100; i++)
        start_thread(threads, [=]{someJob(i);});

    // wait for any unfinished threads    
    for(auto&& thread: threads)
        if(thread.joinable())
            thread.join();
}
like image 55
Galik Avatar answered Sep 28 '22 13:09

Galik


You can simply use std::async for that.

If you want to execute this function 100 times in 5 different asynchronous actions , then each asynchronous function will execute the function 20 times:

std::vector<std::future> results;
results.reserve(5);
for (auto i = 0; i< 5 ;i++){
   results.emplace_back([]{
     for(auto j = 0; j < 20 ; j++){
       doSomeFunction();
     } 
   });
}

for (auto& f : results){
    f.get();
}

the same code can be modified to use naked std::thread.

like image 36
David Haim Avatar answered Sep 28 '22 13:09

David Haim


You should use a Thread Pool.

Specifically, you might use the C++ Thread Pool Library CPTL, with which your code would look like this:

ctpl::thread_pool p(2 /* two threads in the pool */);

for (int i = 0; i < 100; i++) {
    p.push(someJob, "additional_param");
}
like image 40
rakwaht Avatar answered Sep 28 '22 15:09

rakwaht