Presentation is loading. Please wait.

Presentation is loading. Please wait.

8-1 JMH Associates © 2004, All rights reserved Windows Application Development Chapter 10 - Supplement Introduction to Pthreads for Application Portability.

Similar presentations


Presentation on theme: "8-1 JMH Associates © 2004, All rights reserved Windows Application Development Chapter 10 - Supplement Introduction to Pthreads for Application Portability."— Presentation transcript:

1 8-1 JMH Associates © 2004, All rights reserved Windows Application Development Chapter 10 - Supplement Introduction to Pthreads for Application Portability

2 8-2 JMH Associates © 2004, All rights reserved OBJECTIVESOBJECTIVES Upon completion of this chapter, you will be able to:  Describe the Pthreads API  Compare Windows and Pthreads  Use the open source Pthreads library  Build portable threaded applications  Understand threading outside the Windows context

3 8-3 JMH Associates © 2004, All rights reserved 1. Pthreads Overview POSIX Pthreads features supported by:  An industry standard  Similar to Windows, with differences (Ex: Events)  Nearly every UNIX distribution – HP UX, Solaris, AIX, …  Linux  OpenVMS  Others  PLUS, an open source Windows distribution  Cautiously recommended – Trust but verify http://sources.redhat.com/pthreads-win32/ pthread.h pthreadVSE.lib pthreadVSE.dll

4 8-4 JMH Associates © 2004, All rights reserved 2. Thread Management and Creation A parent thread creates a child thread using: int pthread_create (pthread_t *thread, const pthread_attr_t *attr void *(*start) (void *), void *arg); Thread creation notes:  pthread_attr_t is NULL (for our purposes)  Use other values only when explicitly required  Parent and child concepts are for convenience only  Operating system does not maintain any such relationship  The main() program initial thread is special  Behaves differently from other threads

5 8-5 JMH Associates © 2004, All rights reserved Thread Startup The child thread is created in the ready state  It can run immediately Thread startup notes:  Parent and child threads can run in any order  Child thread might complete before (or after) any other  Complete all initialization before calling pthread_create()  Each child thread should have its own data structure  For parameters  For working storage  The parent thread initializes the structure and passes its address in arg

6 8-6 JMH Associates © 2004, All rights reserved Thread Running and Blocking The operating system scheduler runs a thread according to thread priorities and scheduling policies  A thread can run at any time  A thread may run until one of the following:  The thread times out and the operating system preempts it  The thread blocks due to a page fault  The thread terminates or is terminated  The thread yields the processor and moves to the ready state int sched_yield (void);  The thread blocks by calling a blocking function int pthread_join (pthread_t thread, void **value_ptr);

7 8-7 JMH Associates © 2004, All rights reserved Thread Termination The normal way for a thread to terminate is to return from its start function or to call int pthread_exit (void *value_ptr); The return value is the thread’s exit code  Exit code can be accessed by pthread_join() Resources created by a thread must be explicitly released

8 8-8 JMH Associates © 2004, All rights reserved 3. Mutexes A mutex, of object type pthread_mutex_t, can be initialized by assignment or a function call pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; int pthread_mutex_init (pthread_mutex_t *mutex, pthread_mutexattr_t *attr); int pthread_mutex_destroy (pthread_mutex_t *mutex);

9 8-9 JMH Associates © 2004, All rights reserved Mutex Management Notes pthread_mutex_t  Do not copy a variable of type pthread_mutex_t  If declared outside the main function, it should have either extern or static storage class Each mutex must be initialized before it is used Static initialization with PTHREAD_MUTEX_INITIALIZER Dynamic initialization with pthread_mutex_init() When no longer required, destroy it to free kernel and user resources

10 8-10 JMH Associates © 2004, All rights reserved Locking and Unlocking a Mutex A thread can lock or own a mutex  A thread attempts to gain ownership with a try call int pthread_mutex_trylock ( pthread_mutex_t *mutex);  Returns with 0 if successful  Returns with EBUSY if the mutex is owned by another thread  A thread waits to gain ownership with lock call int pthread_mutex_lock (pthread_mutex_t *mutex);  Blocking call; will only return with mutex ownership  Returns with EINVAL if the parameter is not valid  Unlock a mutex int pthread_mutex_unlock ( pthread_mutex_t *mutex);

11 8-11 JMH Associates © 2004, All rights reserved Locking and Unlocking Notes  There is no timeout associated with pthread_mutex_lock()  If a thread terminates before it unlocks a mutex, the mutex remains locked  A mutex can have the recursive attribute  If pthread_mutex_trylock() fails, do not access the protected resources and do not unlock the mutex  Do not let a thread unlock a mutex it does not own  Exactly one blocked thread will be given mutex ownership  You cannot predict which one

12 8-12 JMH Associates © 2004, All rights reserved 4. Condition Variables A condition variable is used to signal that some event or state change has occurred  A mutex protects the whole state data structure  Multiple condition variables related to one mutex  Condition variables represent distinct states  New data available in a buffer  Buffer empty, buffer full, etc.  Signaled to awaken just one thread  Broadcast to awaken all waiting threads Combines: Signal, wait, wait sequence of the CVM

13 8-13 JMH Associates © 2004, All rights reserved Condition Variable Management pthread_cond_t cond = PTHREAD_COND_INITIALIZER; int pthread_cond_init ( pthread_cond_t *cond, pthread_condattr_t *condattr); int pthread_cond_destroy ( pthread_cond_t *cond);

14 8-14 JMH Associates © 2004, All rights reserved Waiting on a Condition Variable Wait with either a blocking wait or a wait with a timeout  Both must specify a mutex  The calling thread must own the mutex before waiting on the condition variable int pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex); int pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex, struct timespec *expiration); Returns ETIMEOUT if the timeout period expires

15 8-15 JMH Associates © 2004, All rights reserved Condition Variable Waiting Notes  A thread “waits” on a condition variable  All threads waiting on a condition variable at any one time must specify the same mutex  Distinct predicates should have distinct condition variables  Associate the condition variable with a state predicate  The mutex should be the one that protects the state variables that determine the predicate  Two distinct predicates  Invariant predicate  Condition variable predicate (implies invariant)  Condition variables are for signaling, not mutual exclusion

16 8-16 JMH Associates © 2004, All rights reserved Condition Variable Signal and Broadcast  Wake up a single waiting thread with int pthread_cond_signal ( pthread_cond_t *cond);  Cannot directly control which of several threads will awaken  Wake up all threads with int pthread_cond_broadcast ( pthread_cond_t *cond);  All waiting threads wake up and immediately block on the mutex  Only one thread, at most, gains mutex ownership immediately

17 8-17 JMH Associates © 2004, All rights reserved CV Waiting and Signaling Threads Thread AThread B Running Ready Running Ready Waiting on cond Lock (&state.guard) Unlock (&state.guard) Lock (&state.guard) Signal (&state.cond) change state variables Wait (&state.cond, &state.guard) Thread A does not own state.guard Running Blocked on guard Ready Thread A owns state.guard change state variables Unlock (&state.guard) ivp() : invariant predicate cvp() : condition variable predicate Run Preempt ivp( ) is true cvp( ) is true

18 8-18 JMH Associates © 2004, All rights reserved Safe Condition Variable Usage Test your predicate immediately before and immediately after the condition variable wait call  A simple while() loop achieves these tests  Develop two thread-safe functions: cvp() implies ivp()  They check the CV predicate and invariant predicate  They check relationships in the state variable structure  Must be called with the appropriate mutex locked  No need for a function for simple predicates

19 8-19 JMH Associates © 2004, All rights reserved Safe Condition Variable Usage typedef struct _state_t { pthread_mutex_t guard; pthread_cond_t cond;... other condition variables struct state_var_t state_var; } state_t state = { PTHREAD_MUTEX_INTIALIZER, PTHREAD_COND_INITIALIZER };... pthread_mutex_lock (&state.guard); /* Change the variables in the state structure */... state.state_var.xyz =... ; /* We know that ivp(&state) holds, wait for cvp(&state) */ /* Do not wait if cvp() already is true, avoid lost wakeup */ while (!cvp(&state)) pthread_cond_wait (&state.cond, &state.guard);... pthread_mutex_unlock (&state.guard);

20 8-20 JMH Associates © 2004, All rights reserved 5. Lab Exercise 10-pthreads Modify eventPC.c (Session 2) to use Pthreads eventPCPT.c is a solution


Download ppt "8-1 JMH Associates © 2004, All rights reserved Windows Application Development Chapter 10 - Supplement Introduction to Pthreads for Application Portability."

Similar presentations


Ads by Google