I have a function that is called millions of times, and the work done by this function is multithreaded. Here is the function:
void functionCalledSoManyTimes()
{
for (int i = 0; i < NUM_OF_THREADS; i++)
{
pthread_create(&threads[i], &attr, thread_work_function, (void *)&thread_data[i]);
}
// wait
}
I'm creating the threads each time the function is called, and I give each thread its data struct (that's been set once at the beginning of the algorithm) to use in the thread_work_function
. The thread_work_function
simply processes a series of arrays, and the thread_data
struct contains pointers to those arrays and the indices that each thread is responsible for.
Although multithreading the algorithm in this way did improve the performance by more than 20%, my profiling shows that the repetitive calls to pthread_create are causing a significant overhead.
My question is: Is there a way to achieve my goal without calling pthread_create
each time the function is called?
Problem Solved.
Thank you guys, I really appreciate your help! I've written a solution here using your tips.
pthread is outdated since availability of C11 which introduced standard threading in C. The header files is <threads. h> with functions like thrd_create . The standard functions for threading, conditions, and signalling, provide guarantees that pthreads cannot.
Threads are concurrently running functions that operate within a single process. Each thread in a process belongs to the same address (memory) space and thus shares memory with the other threads in the process. Threads can communicate with one another by writing to and reading from addresses in the shared memory.
pthreads is a parallel execution model and we use the pthread library to create and manage pthreads in the operating system. pthread library gives an IEEE standardized API that consists of different functions to perform thread operations. The standardization is done to make code portable.
The Pthreads standard specifies concurrency; it allows parallelism to be at the option of system implementors. As a programmer, all you can do is define those tasks, or threads, that can occur concurrently.
Just start a fixed set of threads and use an inter-thread communication system (ring buffer, for instance) to pass the data to process.
Solving the problem gracefully is not so easy. You can use static storage for a thread pool, but then what happens if functionCalledSoManyTimes
itself can be called from multiple threads? It's not a good design.
What I would do to handle this sort of situation is create a thread-local storage key with pthread_key_create
on the first call (using pthread_once
), and store your thread-pool there with pthread_setspecific
the first time functionCalledSoManyTimes
gets called in a given thread. You can provide a destructor function to pthread_key_create
which will get called when the the thread exists, and this function can then be responsible for signaling the worker threads in the thread pool to terminate themselves (via pthread_cancel
or some other mechanism).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With