Download presentation
Presentation is loading. Please wait.
Published byMervyn Copeland Modified over 9 years ago
1
Chapter 6 P-Threads
2
Names The naming convention for a method/function/operation is: – pthread_thing_operation(..) – Where thing is the object used (such as mutex, condition, etc) – operation is what to do (such as init, lock, etc) – To operate on the thread itself, leave off the thing Such as pthread_create, pthread_join Types end in _t rather than the operation
3
Create a Thread int pthread_create(pthread_t *TID, const pthread_attr_t *attr, void * (*start_routine)(void *), void *arg) TID – thread identifier attr – a pthread attribute object (can be NULL for default values) start_routine – the name of the function for the new thread to start execution at. arg – the argument to pass to the starting function. Use a struct if want to pass more than 1 value
4
Thread operations pthread_t pthread_self() – returns thread id of the current thread. int pthread_equal(pthread_t t1, pthread_t t2) – returns 0 if t1 and t2 are not the same thread, returns not 0 otherwise. int sysconf(_SC_THREAD_THREADS_MAX) – Returns the maximum number of threads the system can handle – Not a pthreads function but a system call – Google sysconf for more functionality
5
Coordinating Threads int pthread_join(pthread_t TID, void **valuep) – Waits until thread TID has completed (no wait if it has already completed – valuep has the value returned by the function the thread started – If several threads are waiting for the same thread, only one of the waiting threads get the return value. Others have a value returned by pthread_join being ESRCH (from errno.h)
6
Ending a Thread Explicitly – Calling pthread_exit(void *valuep) to exit and return the value – return Implicitly – pthread_exit() called implicitly when function terminates Remember all local variable are destroyed.
7
Sidenote – faking a 2-D array with 1-D Want an array A(m, n); fake with B(m*n) Using a row major ordering, A(i,j) is at B(i*n+j) Using column major, A(i,j) is at B(i+j*m) Look at figure 6.1 together
8
Thread Coordination Need to be able to restrict a variable to exclusive use in order to prevent race conditions Pthreads uses 2 things: mutex and condition variables
9
Mutex type To get a mutex variable declare it of type pthread_mutex_t Mutex variables have 2 states, locked and unlocked Need a mutex variable for each memory area that you want to allow mutually exclusive access. This association is implied by program coding. Can make it more explicit by grouping the mutex variable with its associated mutually exclusive structure into the same struct
10
Mutex Use For mutually exclusive use, every thread must – Lock the mutex before using the structure – If successful, this thread is the owner of the mutex variable – After finishing mutually exclusive use of the memory area, the thread must unlock the mutex variable and is no longer the owner of the mutex variable
11
Lock and Unlock concepts If a thread tries to lock a mutex variable owned by another thread, then the thread that is not the owner is blocked until the mutex variable is unlocked int pthread_mutex_lock(pthread_mutex_t *mutex) int pthread_mutex_unlock(pthread_mutex_t *mutex) int pthread_mutex_trylock(…) – Gets ownership of mutex if mutex is available, returns EBUSY if not available – Does not block/wait for lock. This thread can now do other work rather than waiting.
12
Mutex Variables Two ways to initialize a mutex variable mutex_var=PTHREAD_MUTEX_INITIALIZER – Can be used only with static variables for the default initial values Can call the init function – int pthread_mutex_init(pthread_mutex_t *mutex_var, const pthread_mutexattr_t *attr) – Can be done on static or dynamic mutex variables – Can use NULL as the attr for default
13
Deadlocks with Mutexs Thread 1 locks m1 then m2. Thread 2 locks m2 then m1. No unlocking happening between the locking. If execution happens in the order t1 locks m1, t2 locks m2, then t1 waits for m2 while t2 waits for m1. Can be avoided by having every thread use the same locking order. Backing off – if cannot lock a mutex, unlock all the mutexs already locked and try again from the beginning.
14
Condition Variables May need a certain condition to be true on a variable in a critical area before progressing – So the method would be Get mutex –lock Check value – if ok proceed If not ok, release mutex and try again – Uses execution resources – busy wait loop. – Nicer if blocked and waiting so other processes could use the cpu – This is what Condition Variables (and operations) give us
15
Using Condition Variables pthread_cond_t cond_var int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t * attr) pthread_cond_t cond = PTHREAD_COND_INITIALIZER A condition variable is used with a mutex variable.
16
Programming Condition Variables First a mutex must be locked int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t * mutex) – Typical code pattern: pthread_mutex_lock (&mutex); while (!condition() ) pthread_cond_wait(&cond, &mutex); Do something pthread_mutex_unlock(&mutex); – If condition is not true, the thread waits and the mutex is implicitly released. When another thread signals the condition, the waiting threads are unblocked. Hence the need for while (rather than if).
17
Condition Signal int pthread_cond_signal(pthread_cond_t *cond); – Wakes up a single waiting thread (no effect if none waiting) int pthread_cond_broadcast(pthread_cond_t *cond); – Wakes up all waiting threads
18
Topics You can skip R/W _lock Read about task pools Read about pipelining Read about client server Read about producer consumer
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.