MANGLED MUTEXES
• •
MULTI THREAD PRIME NUMBER COUNTER
Learn how to use pthread to parallelize your program.
Learn how to use mutex to protect data structures shared between thread.
•
• •
COUNT_PRIME.C
Try all the numbers from 1 to sqrt(N) to see if N is divisible by them
If it is divisible, then it’s not a prime
If after checking all the numbers and it’s not divisible, then it’s a prime
PARALLELIZE
SQRT(N)
COUNT_PRIME #PRIMES
How to split your job?
GROUP I
PARALLELIZE SPLIT THEN DOMAIN
COUNT_PRIME
COUNT_PRIME
COUNT_PRIME
GROUP II
#PRIMES
GROUP III
COUNT_PRIME
COUNT_PRIME
COUNT_PRIME
#PRIMES
May be updated simultaneously!
PROBLEM TO SOLVE
• •
•
•
•
•
HINT
Use a mutex to protect your global variable.
Divide the domain of your function and use one thread for each of them.
For each thread, they need to know the domain(group of numbers) they are working on.
• For each thread, update the global variable when it’s done. pthread_create(pthread_t*, const pthread_attr_t * attr,
void*(*start_routine)(void*), void * args);
What to pass to “start_routine” and “args? Write a single threaded version first!!!!!!
•
• •
• •
PTHREAD
pthread_create( pthread_t* thread, const pthread_attr_t* attr, void* (*start_routine) (void*), void *arg);
pthread_t is the id of the thread you create
attr is some attribute setting, set it to NULL if you want default setting
start_routine is the function you want to wrong
arg is the pointer to arguments you want to pass to start_routine
WHY VOID* GENERIC PROGRAMMING
pthread_create( pthread_t* thread, const pthread_attr_t* attr, void* (*start_routine) (void*), void *arg);
If we specify the return type and arguments type for start_routine
(int*) (*start_routine)(int), int arg
(double*) (*start_routine)(double), double arg ….. // need a lot of version
What if user want to pass in some customized objects as arguments?
•
•
•
•
•
•
•
•
WHY VOID* GENERIC PROGRAMMING
If we use (void*)
void * is big enough to hold any data pointer
•
• •
we can wrap all the arguments we need in a struct
•
• typedef struct{ int a; double b; char c;} myArgs;
pthread_create( pthread_t* thread, const pthread_attr_t* attr, void* (*start_routine) (void*), void *arg);
start_routine can therefore be customized as you need
System does not need to provide a lot of different version of pthread_create.
PTHREAD SPLIT THEN DOMAIN
DOMAIN THREAD_I
pass args
start_routine( args)
#PRIMES
• •
pthread_create( t_id, attr, start_routine, args) wrap your domain information in args
PRIME COUNTER FUNC
DOMAIN
1-100 THREAD_I
101-200 THREAD_II
201-300 THREAD_III
pass args
update
#PRIMES update
PTHREAD
PRIME COUNTER FUNC
start_routine( args)
PRIME COUNTER FUNC
pass args
pass args
start_routine( args)
PRIME COUNTER FUNC
start_routine( args