View Single Post
Old 16th April 2019, 20:32   #4  |  Link
LoRd_MuldeR
Software Developer
 
LoRd_MuldeR's Avatar
 
Join Date: Jun 2005
Location: Last House on Slunk Street
Posts: 13,248
Put simply, you create a fixed number of "worker" threads once, and you keep them running continuously – instead of creating short-lived threads for each task.

Each "worker" thread executes an infinite loop that looks like this:
Code:
void thread_main(void)
{
    while(!g_isTerminating)
    {
        Task nextTask = g_queue.take();
        nextTask.execute();
    }
}
In the above code, it is assumed that the queue g_queue is global, i.e. shared between all worker threads (as well as with the rest of the application), and that it is synchronized, i.e. thread-safe. Also, it is assumed that take() returns the "next" item from the queue and removes that item from the queue at the same time – both in a single "atomic" operation. Last but not least, it is assumed that take() will block, while there is no item left in the queue.

Now, in order to have some task executed by the thread pool, you simply push the task object onto the queue, e.g. from the "main" thread, and that's it:

Code:
void main(void)
{
    /* .... */

    for(int i = 0; i < numberOfTasks; ++i)
    {
        Task taskToBeExecuted = new Task(/*task-specific parameters go here*/);
        g_queue.push(taskToBeExecuted);
    }

    /* .... */
}
This is actually an example of the well-known producer consumer pattern. Here the "main" thread is the producer, i.e. it produces tasks, and the "worker threads" are consumers, i.e. they consume tasks.

BTW: Because most "standard" queue implementations, such as C++'s std::queue, are not thread-safe, you will usually need to use a mutex in order to synchronize things. Also, in order to implement the case that the queue is empty – you want your threads to sleep in that case, instead of doing a highly inefficient "busy waiting" – you will probably have to use condition variables. Well, either that, or forget everything I said and just use C++11's std::async()
__________________
Go to https://standforukraine.com/ to find legitimate Ukrainian Charities 🇺🇦✊

Last edited by LoRd_MuldeR; 16th April 2019 at 21:36.
LoRd_MuldeR is offline   Reply With Quote