Implementation of libraries to manage a group of worker threads, assign them concurrent tasks asynchronously and await for computations' results using Future mechanism.
Project for the course "Concurrent programming" at my Computer Science studies.
typedef struct runnable {
void (*function)(void *, size_t);
void *arg;
size_t argsz;
} runnable_t;
typedef struct thread_pool thread_pool_t;
int thread_pool_init(thread_pool_t *pool, size_t pool_size);
void thread_pool_destroy(thread_pool_t *pool);
int defer(thread_pool_t *pool, runnable_t runnable);
- Execution
thread_pool_init(*pool, pool_size)
initialize resource and runpool_size
worker-threads related with thread pool referenced aspool
. - Execution
thread_pool_destroy(*pool)
block adding new tasks topool
, finish working worker-thread and free all resource associated with thepool
. - Execution
defer(*pool, runnable)
add a new task topool
to asynchronous realisation.
Programs using the Thread pool have setting SIGINT signal handling. After receiving a signal, all working pools block deferring new tasks and finish their current tasks.
typedef struct callable {
void *(*function)(void *, size_t, size_t *);
void *arg;
size_t argsz;
} callable_t;
typedef struct future future_t;
int async(thread_pool_t *pool, future_t *future, callable_t callable);
int map(thread_pool_t *pool, future_t *future, future_t *from,
void *(*function)(void *, size_t, size_t *));
void *await(future_t *future);
- Execution
async(*pool, *future, callable)
defer a new task to realisation forpool
and initializefuture
to receipt result of a computation. - Execution
map(*pool, *future, *from, *(*function)(void*, size_t, size_t*))
defer a task to realisation forpool
with argument received fromfrom
future related with previous defered task. - Execution
await(future_t *future)
block the current thread until receive result of deferred computation related withfuture
.
Getting result from future_t
object more than once is undefined behaviour (similar to C++ thread pool)
Part of assigment was write two programs uses own implementation of thread pool.
Program read two numbers k
and n
from standard input. Then read n*k
lines which represent cells of a matrix with k
rows and n
columns.
Every line has two number: the value of cell and time needed for computing value in cell (in milliseconds).
The program "computes" every value in cell (by waiting), sums all values in each row and print them to standard output.
Example:
2
3
1 2
1 5
12 4
23 9
3 11
7 2
This data represents that matrix:
| 1 1 12 |
| 23 3 7 |
and gives as result:
14
33
The factorial program read a single number n
from the standard input, and then calculate the number n!
using a pool of 3 threads. After calculating print result to standard output. The program MUST (according to requirements) calculate the factorial using the map
function and passing it as partial products.
Example:
6
gives:
720