Thread pool stucks

161 views Asked by At

I created a thread pooling to distribute 100 computations between 4 threads.

I cannot understand why the following code stucks after 4 computations. After each computation, the thread must be released and I expect that .joinable() returns false so the program will continue.

Results:

[[[01] calculated 
] calculated 
2] calculated 
[3] calculated 

Code:

#include <string>
#include <iostream>
#include <vector>
#include <thread>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/thread/thread.hpp>
#include <cmath>

class AClass
{
public:

    void calculation_single(std::vector<double> *s,int index)
    {
        (*s)[index]=sin(double(index));
        std::cout<<"["<<index<<"] calculated \n";
    }

    void calculation()
    {
        const uint N_nums=100;
        const uint N_threads=4;
        std::vector<double> A;
        A.assign(N_nums,0.0);
        std::vector<std::thread> thread_pool;
        for(uint i=0;i<N_threads;i++)
            thread_pool.push_back(std::thread());

        uint A_index=0;
        while(A_index<N_nums)
        {
            int free_thread=-1;
            for(uint i=0;i<N_threads && free_thread<0;i++)
                if(!thread_pool[i].joinable())
                    free_thread=i;
            if(free_thread>-1)
            {
                thread_pool[free_thread]=
                    std::thread(
                        &AClass::calculation_single,
                        this,
                        &A,
                        int(A_index));
                A_index++;
            }
            else
            {
                boost::this_thread::sleep(boost::posix_time::milliseconds(1));
            }

        }

        // wait for tasks to finish
        for(std::thread& th : thread_pool)
            th.join();
    }

};

int main()
{
    AClass obj;
    obj.calculation();
    return 0;
}
1

There are 1 answers

8
Yakk - Adam Nevraumont On

A thread is joinable if it isn't empty basically.

A thread with a completed task is not empty.

std::thread bob;

bob is not joinable.

Your threads are. Nothing you do makes them not joinable.

Also, busy waiting is a crappy thread pool.

Create a consumer producer queue, with a pool of threads consuming tasks and an abort method. Feed tasks into the queue with via a packaged task and return a std::future<T>. Don't spawn a new thread per task.