Reputation: 41
So, I am currently writing a program that uses the standard pthread.h
library.
I want there to be multiple threads, all calculating stuff independently of each other at the same time (no mutexes needed). The main
function needs to handle the return values of each thread (add them to an array/ linked list or something).
I could do something like this:
// the threads have already been created
data_type *data; // assume this has been allocated properly etc
pthread_join(thread_id, (void *)data);
list_insert(head_of_list, data);
However, here is where my problem lies. From my understanding, when I repeat this in a loop for every thread, the code isn't optimized at all, because if every thread has finished running but the first, we would have to wait for the first to finish before recreating threads. Assuming a fixed amount of threads:
// still already initialized
for(int i=0; i<amount_of_threads; i++){
data_type *data; // assume this has been allocated etc properly
pthread_join(array_of_thread_ids[i], (void *)data);
list_insert(head_of_list, data);
// create new thread with new job here
}
What I want the main function to do, is as soon as any of the threads finish running, do what is in the for loop for that specific thread and then continue waiting for the next one to finish. How can I solve this problem?
I have been rummaging around the internet but I have yet to find something that works efficiently. Surely I must be missing something.
Thank you in advance. Cheers
Upvotes: 4
Views: 93
Reputation: 25326
Creating a thread is a rather expensive operation. Therefore, insteading of creating, destroying and recreating threads all the time, it is generally more efficient to create all threads that you will be needing at once, and then to reuse these threads as necessary. This is called a thread pool.
If you decide to create such a thread pool, then what you have is essentially a producer-consumer problem with multiple producers and/or consumers. This problem can be solved with condition variables and mutexes, which are both supported by pthreads.
The main thread could keep feeding the work to be done by the thread pool into a data structure, such as a queue or a priority queue. This queue could be protected by a mutex, so that all threads can read from and write to this queue in a thread-safe manner. You may also want a second queue for the threads in the thread pool to store the results of their work, so that the main thread can process/merge these results. You may want to use a separate mutex for protecting this second queue, especially if the amount of data stored in a single queue element is significant.
You will probably want the main thread and the threads in the thread pool to fall asleep in certain situations, such as when one of the queues mentioned above gets full or empty. This is generally better than busy waiting. For example, you may want
You can make a thread fall asleep and wait on a condition variable by using the function pthread_cond_wait
. Another thread can wake up such a waiting thread by using pthread_cond_signal
or pthread_cond_broadcast
on the condition variable.
Upvotes: 3
Reputation: 386541
I'd create a pool of workers, feed them work through a thread-aware queue, and collect the results using one as well.
Upvotes: 3