How to utilize a thread pool with pthreads?
Asked Answered
B

2

25

I have a queue of jobs and I want to make a pool of four threads where I can throw my jobs at. What I am stuck at is in how to make the threads and keep them suspended while there is no work.

JOB QUEUE        | job1 | job2 | job3 | job4 | ..

THREAD POOL      | thread1 | thread2 | thread3 | thread4 |

To create the threads I have currently at the initialisation point:

for (t=0; t<num_of_threads; t++){
    pthread_create(&(threads[t]), NULL, doSth2, NULL);
}

Where num_of_threads=4 and doSth2 is a function with nothing inside. So once I have created the 4 threads and they are done with doSth2, how can I give them new work to do, without killing them?

Biggs answered 5/8, 2011 at 9:53 Comment(0)
S
21

The key to a thread pool is a queue. Here are modified functions for a thread pool I have developed.

Put element in queue

void queue_add(queue q, void *value)
{
    pthread_mutex_lock(&q->mtx);

    /* Add element normally. */

    pthread_mutex_unlock(&q->mtx);

    /* Signal waiting threads. */
    pthread_cond_signal(&q->cond);
}

Get element from queue

void queue_get(queue q, void **val_r)
{
    pthread_mutex_lock(&q->mtx);

    /* Wait for element to become available. */
    while (empty(q))
        rc = pthread_cond_wait(&q->cond, &q->mtx);

    /* We have an element. Pop it normally and return it in val_r. */

    pthread_mutex_unlock(&q->mtx);
}
Satiate answered 5/8, 2011 at 10:0 Comment(4)
Thank you. I get the idea now.. Each thread in the pool is supposed to read from the queue serially. Though how do you go with pausing the threads if the queue is empty so that they don't eat up the cpu?Biggs
@Biggs pthread_cond_wait blocks until someone (queue_add) signals cond.Satiate
Sorry to open this so late but if the queue_get is locking the mtx and then looping, how can you add an item if mtx is locked? Shouldn't the lock be after the loop (e.g. loop -> lock -> pop -> unlock)?Heiress
A while ago I know - to answer @AlexandreGomes - pthread_cond_wait (from man [linux.die.net/man/3/pthread_cond_wait]) unlocks the mutex while waiting, for other thread to use, and returns having locked it again. Hence the mutex is passed as a parameter.Ruble
G
5

As an alternate riff on cnicutar's answer you can just use POSIX message queues which will take care of the synchronization concerns in the kernel. There will be some small overhead for the system calls which may or may not be a concern. It is pretty minimal as the kernel is doing everything you would have to do manually anyway.

The consumer threads can just block on mq_receive and if you create a special type of queue message it makes it easy to tell the threads when to shut down.

Giralda answered 5/8, 2011 at 15:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.