Low-level threading and synchronization support Pthreads POSIX
threads IEEE POSIX 1003.1c (1995) C library All POSIX compliant
systems (even Windows) ISO C++ 2011 Standard libraries New
compilers Currently only partial support
Threads Create attr==NULL default attributes int
pthread_create(pthread_t *thread, pthread_attr_t *attr, void
*(*start_routine)(void *), void *arg); Exit Return value_ptr to
join void pthread_exit(void *value_ptr); Join Suspend calling
thread and wait for exit int pthread_join(pthread_t thread, void
**value_ptr);
Slide 5
Threads join
Slide 6
Threads joinable, detached Joinable Only joinable threads can
be joined Should be by default joinable Explicitly set joinability
for greater compatibility Detached Explicitly set by attributes
Cannot be joined Some resources can be spared
Slide 7
Threads misc Get my ID pthread_t pthread_self(void); Compare
thread IDs int pthread_equal(pthread_t t1, pthread_t t2);
Initialize once int pthread_once(pthread_once_t *once_control, void
(*init_routine)(void)); pthread_once_t once_control =
PTHREAD_ONCE_INIT; Kill int pthread_kill(pthread_t thread, int
sig);
Slide 8
Thread attributes Initialize attributes int
pthread_attr_init(pthread_attr_t *attr); Destroy attributes int
pthread_attr_destroy(pthread_attr_t *attr); Set/get int
pthread_attr_getXXX(const pthread_attr_t *attr, TTT *av); int
pthread_attr_setXXX(pthread_attr_t *attr, TTT av);
Mutexes Create int pthread_mutex_init(pthread_mutex_t *mutex,
const pthread_mutexattr_t *mutexattr); Destroy int
pthread_mutex_destroy(pthread_mutex_t *mutex); Attributes Protocol,
sharing, int pthread_mutexattr_init(pthread_mutexattr_t *attr); int
pthread_mutexattr_destroy(pthread_mutexattr_t *attr); int
pthread_mutexattr_getXXX(const pthread_mutexattr_t *attr, TTT *av);
int pthread_mutexattr_setXXX(pthread_mutexattr_t *attr, TTT
av);
Slide 11
Mutexes locking Blocking lock int
pthread_mutex_lock(pthread_mutex_t *mutex); Non-blocking lock int
pthread_mutex_trylock(pthread_mutex_t *mutex); Unlock int
pthread_mutex_unlock(pthread_mutex_t *mutex);
Slide 12
Condition variables Create int pthread_cond_init(pthread_cond_t
*cond, const pthread_condattr_t *attr); Destroy int
pthread_cond_destroy(pthread_cond_t *cond); Attributes Clock,
sharing, int pthread_condattr_destroy(pthread_condattr_t *attr);
int pthread_condattr_init(pthread_condattr_t *attr); int
pthread_condattr_getXXX(const pthread_condattr_t *attr, TTT *av);
int pthread_condattr_setXXX(pthread_condattr_t *attr, TTT av);
Slide 13
Condition variables locking Blocking wait int
pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
Blocking timed wait int pthread_cond_timedwait(pthread_cond_t
*cond, pthread_mutex_t *mutex, const struct timespec *abstime);
Unblock one int pthread_cond_signal(pthread_cond_t *cond); Unblock
all int pthread_cond_broadcast(pthread_cond_t *cond);
Slide 14
R/W lock Create int pthread_rwlock_init(pthread_rwlock_t
*rwlock, const pthread_rwlockattr_t *attr); Destroy int
pthread_rwlock_destroy(pthread_rwlock_t *rwlock); Attributes
Sharing, int pthread_rwlockattr_destroy(pthread_rwlockattr_t
*attr); int pthread_rwlockattr_init(pthread_rwlockattr_t *attr);
int pthread_rwlockattr_getXXX(const pthread_rwlockattr_t *attr, TTT
*av); int pthread_rwlockattr_setXXX(pthread_rwlockattr_t *attr, TTT
av);
Slide 15
R/W lock reader Blocking lock int
pthread_rwlock_rdlock(pthread_rwlock_t *rwlock); Non-blocking lock
int thread_rwlock_tryrdlock(pthread_rwlock_t *rwlock); Timed lock
int thread_rwlock_timedrdlock(pthread_rwlock_t *rwlock, const
struct timespec *abs_timeout); Unlock int
pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
Slide 16
R/W lock writer Blocking lock int
pthread_rwlock_wrlock(pthread_rwlock_t *rwlock); Non-blocking lock
int thread_rwlock_trywrlock(pthread_rwlock_t *rwlock); Timed lock
int thread_rwlock_timedwrlock(pthread_rwlock_t *rwlock, const
struct timespec *abs_timeout); Unlock int
pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
Slide 17
Barrier Init int pthread_barrier_init(pthread_barrier_t
*barrier, const pthread_barrierattr_t *attr, unsigned count);
Destroy int pthread_barrier_destroy(pthread_barrier_t *barrier);
Wait int pthread_barrier_wait(pthread_barrier_t *barrier);
Attributes Sharing, int
pthread_barrierattr_destroy(pthread_barrierattr_t *attr); int
pthread_barrierattr_init(pthread_barrierattr_t *attr); int
pthread_barrierattr_getXXX(const pthread_barrierattr_t *attr, TTT
*av); int pthread_barrierattr_setXXX(pthread_barrierattr_t *attr,
TTT av);
Slide 18
Spin-lock Create int pthread_spin_init(pthread_spinlock_t
*lock, int pshared); Destroy int
pthread_spin_destroy(pthread_spinlock_t *lock); Wait int
pthread_spin_lock(pthread_spinlock_t *lock); Non-blocking wait int
pthread_spin_trylock(pthread_spinlock_t *lock); Unblock int
pthread_spin_unlock(pthread_spinlock_t *lock);
Slide 19
Thread local storage Create dest_routine called at thread exit
int pthread_key_create(pthread_key_t * key, void (*
dest_routine(void *))); Destroy int
pthread_key_delete(pthread_key_t key); Set int
pthread_setspecific(pthread_key_t key, const void * pointer); Get
void * pthread_getspecific(pthread_key_t key);
Slide 20
ISO C++ 2011 overview Threads Mutexes Condition variables
Atomic variables Futures A future is a token for a value that will
be available later Focus on communication between threads
Synchronization details left to library
Slide 21
Futures std::future Defines a type for asynchronous return
object which do not share their shared state std::shared_future
Like future but may share their shared state std::promise
Explicitly set shared state std::packaged_task Shared state is the
result of a function call std::async Launching a function
potentially in a new thread
Slide 22
Futures example double comp(vector & v) { // package the
tasks: // (the task here is the standard accumulate() for an array
of doubles): packaged_task pt0{std::accumulate }; packaged_task
pt1{std::accumulate }; auto f0 = pt0.get_future(); // get hold of
the futures auto f1 = pt1.get_future();
pt0(&v[0],&v[v.size()/2],0); // start the threads
pt1(&[v.size()/2],&v[size()],0); return f0.get()+f1.get();
// get the results }
Slide 23
Futures async example template struct Accum { // simple
accumulator function object T* b; T* e; V val; Accum(T* bb, T* ee,
const V& v) : b{bb},e{ee},val{vv} {} V operator() () { return
std::accumulate(b,e,val); } }; double comp(vector & v) { //
spawn many tasks if v is large enough if (v.size()