Description #
Your task is to prepare a pool of threads waiting for functions to execute. Unlike creating threads on demand, a thread pool allocates worker threads at the beginning of program execution, and they wait for a signal to perform work. Then, from other threads, you can pass a function to be executed by one thread from the pool.
In this lab, the thread pool should implement three functions:
initialize
– createN
threads within the thread pool.dispatch
– pass a pointer to a function with the signaturevoid (work_function)(void)
and the calling arguments to a thread waiting for work. If there is no free thread to perform the work, thedispatch
function should block until a free thread is found.cleanup
– the function should wait for all worker threads to finish and perform threadjoin
. It is not allowed to interrupt the work of a thread that has taken the task to execute a function.
The loop of a worker thread can be described in the following steps:
Wait on a conditional variable for work assigned from another thread (one conditional variable shared between all worker threads).
After taking over the work function and execution arguments, inform that it has happened. Otherwise, a race condition could occur, leading to unstable thread pool operation.
Call the function with the received arguments.
Repeat until the
cleanup
function is called on the thread pool.
To use the thread pool, a Monte Carlo method for calculating the area of
a circle has been implemented. The procedure consists of two parts:
drawing points and averaging the obtained results. The implementation
using our thread pool realizes these two parts as two different worker
functions: circle_monte_carlo
and accumulate_monte_carlo
. The
accumulate_monte_carlo
function must start averaging the results only
after all circle_monte_carlo
functions have finished. Your task in
this lab is to synchronize these two functions (a barrier is ideal for
this purpose) and provide them with the correct data.
For easier testing, a CLI interface has been implemented within the starter code:
enter command
1. circle <n> <r> <s>
2. hello <n>
3. exit
It allows selecting a command with the corresponding number and passing
arguments separated by spaces. The first command runs the procedure to
calculate the area of a circle with a radius of r
using n
threads in
total, randomizing s
samples in total. The second command runs n
test functions printing Hello world from worker n!
. Choosing the third
option closes the program, waiting for all requested commands to finish.
Hint: Critical places in the code where something needs to be added
in each stage are marked with the comment TODO STAGE-X
.
Stages: #
- Implement the
initialize
function. Created threads should print theirTID
and wait on a conditional variable. - Implement the
dispatch
function. Thehello
option should work at this stage. - Implement
passing data to calculate the area of a circle and synchronization with
the threads drawing points. The
circle
option should work at this stage. - Implement the
cleanup
function. The program should wait for the calculations to finish and correctly terminate all threads when choosing theexit
option.