1 / 29

POSIX threads and C++ facilities

POSIX threads and C++ facilities. Jakub Yaghob. 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.

abril
Download Presentation

POSIX threads and C++ facilities

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. POSIX threads and C++ facilities Jakub Yaghob

  2. 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

  3. Pthreads overview • Thread management • Thread attributes • Mutexes • Condition variables • Synchronization • R/W locks, barriers

  4. 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);

  5. Threads – join

  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

  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);

  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);

  9. Thread attributes – examples • Joinable/detached • XXX = detachstate, TTT = int, av = PTHREAD_CREATE_DETACHED or PTHREAD_CREATE_JOINABLE • Stack • XXX = stacksize, TTT = size_t • XXX = stackaddr, TTT = void* • Scheduling • inheritsched, schedparam, schedpolicy

  10. 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);

  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);

  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);

  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);

  14. R/W lock • Create intpthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr); • Destroy intpthread_rwlock_destroy(pthread_rwlock_t *rwlock); • Attributes • Sharing, … intpthread_rwlockattr_destroy(pthread_rwlockattr_t *attr); intpthread_rwlockattr_init(pthread_rwlockattr_t *attr); intpthread_rwlockattr_getXXX(constpthread_rwlockattr_t *attr, TTT *av); intpthread_rwlockattr_setXXX(pthread_rwlockattr_t *attr, TTT av);

  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);

  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);

  17. Barrier • Init intpthread_barrier_init(pthread_barrier_t *barrier, const pthread_barrierattr_t *attr, unsigned count); • Destroy intpthread_barrier_destroy(pthread_barrier_t *barrier); • Wait intpthread_barrier_wait(pthread_barrier_t *barrier); • Attributes • Sharing, … intpthread_barrierattr_destroy(pthread_barrierattr_t *attr); intpthread_barrierattr_init(pthread_barrierattr_t *attr); intpthread_barrierattr_getXXX(constpthread_barrierattr_t *attr, TTT *av); intpthread_barrierattr_setXXX(pthread_barrierattr_t *attr, TTT av);

  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);

  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);

  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

  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

  22. Futures – example double comp(vector<double>& v) { // package the tasks: // (the task here is the standard accumulate() for an array of doubles): packaged_task<double(double*,double*,double)> pt0{std::accumulate<double*,double*,double>}; packaged_task<double(double*,double*,double)> pt1{std::accumulate<double*,double*,double>}; 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 }

  23. Futures – async example template<class T, class V> structAccum { // simpleaccumulatorfunctionobject T* b;T* e;V val; Accum(T* bb, T* ee, const V& v):b{bb},e{ee},val{vv} {} V operator() () { returnstd::accumulate(b,e,val); } }; double comp(vector<double>& v){ // spawn many tasksif v islargeenough if (v.size()<10000) returnstd::accumulate(v.begin(),v.end(),0.0); auto f0 {async(Accum{&v[0],&v[v.size()/4],0.0})}; auto f1 {async(Accum{&v[v.size()/4],&v[v.size()/2],0.0})}; auto f2 {async(Accum{&v[v.size()/2],&v[v.size()*3/4],0.0})}; auto f3 {async(Accum{&v[v.size()*3/4],&v[v.size()],0.0})}; return f0.get()+f1.get()+f2.get()+f3.get(); }

  24. Threads • Simple low-level access • std::thread • Namespace this_thread • thread::id get_id() • void yield() • void sleep_until(abs_time) • void sleep_for(rel_time) • bool joinable() const • void join() • void detach()

  25. Threads – example void f(); struct F { void operator()(); }; int main() { std::thread t1{f}; // f() executes in separate thread std::thread t2{F()}; // F()() executes in separate thread t1.join(); // wait for t1 t2.join(); // wait for t2 }

  26. Mutexes • Classes • std::mutex • std::recursive_mutex • std::timed_mutex • std::recursive_timed_mutex • Operations • void m.lock() • boolm.try_lock() • void m.unlock() • Timed mutexes operations • booltm.try_lock_for(rel_time) • booltm.try_lock_until(abs_time)

  27. Condition variables • Class std::condition_variable • void notify_one() • void notify_all() • void wait() • bool wait_for(rel_time) • bool wait_until(abs_time) • Class std::condition_variable_any • Use any mutex

  28. Locks • Class std::lock_guard • Scope lock • Class std::unique_lock • Controls ownership • Generic lock template <class L1, class L2, class... L3> void lock(L1&, L2&, L3&...); • Call once classinformation { std::once_flag verified; voidverifier(); public: voidverify() { std::call_once(verified,verifier); } };

  29. Atomic variables • Generic template atomic • compare_exchange • load, store • Specialization for basic types • fetch_add, fetch_sub, fetch_and, fetch_or, fetch_xor • Class atomic_flag • bool test_and_test() • Fences

More Related