Sysprog 14

60 %
40 %
Information about Sysprog 14

Published on April 27, 2009

Author: linuxawy

Source: slideshare.net

C/C++ Linux System Programming Session 14 User-space System Programming – session 4

Session 14

User-space System Programming

– session 4

Outline Threads: Concepts and Linux Implementation Creation and Termination Cancellation Mutual Exclusion and Threads Process vs. Threads

Threads: Concepts and Linux Implementation

Creation and Termination

Cancellation

Mutual Exclusion and Threads

Process vs. Threads

Threads A lightweight process: Share address space (unlike process) Another execution context (like a process) Why? IPC Dedicated (blocking) listener: Consider IPC or Device case

A lightweight process:

Share address space (unlike process)

Another execution context (like a process)

Why?

IPC

Dedicated (blocking) listener: Consider IPC or Device case

Linux Implementation of Threads Clone system call: Part of a thread group (2.6): all have same TGID (PID) Have separate TID (gettid) Same signal dispositions (separate masks) Any thread can wait for the child of any other thread A common VM Ability to pass start of exec stack Scheduled and context-switched as processes Rest is in User-space (libpthread.so)

Clone system call:

Part of a thread group (2.6):

all have same TGID (PID)

Have separate TID (gettid)

Same signal dispositions (separate masks)

Any thread can wait for the child of any other thread

A common VM

Ability to pass start of exec stack

Scheduled and context-switched as processes

Rest is in User-space (libpthread.so)

Pthread Object “Template”: pthread_xxx_t int pthread_xxx_init (pthread_xxx_t *obj, pthread_xxxattr_t *attr); int pthread_xxx_destroy (pthread_xxx_t *obj);

pthread_xxx_t

int pthread_xxx_init (pthread_xxx_t *obj, pthread_xxxattr_t *attr);

int pthread_xxx_destroy (pthread_xxx_t *obj);

Attribute Objects “Template”: Initialization/Deletion of type xxx: int pthread_xxxattr_destroy(pthread_xxxattr_t *attr); int pthread_xxxattr_init(pthread_xxxattr_t *attr); get/set attribute type xxx, attribute aaa: int pthread_xxxattr_getaaa(pthread_xxxattr_t *attr, int *val); int pthread_xxxattr_setaaa(pthread_xxxattr_t *attr, int val);

Initialization/Deletion of type xxx:

int pthread_xxxattr_destroy(pthread_xxxattr_t *attr);

int pthread_xxxattr_init(pthread_xxxattr_t *attr);

get/set attribute type xxx, attribute aaa:

int pthread_xxxattr_getaaa(pthread_xxxattr_t *attr, int *val);

int pthread_xxxattr_setaaa(pthread_xxxattr_t *attr, int val);

Thread creation / termination int pthread_create(pthread_t *restrict thread, const pthread_attr_t *restrict attr, void *(*start_routine)(void*), void *restrict arg); void pthread_exit(void *value_ptr); Thread attributes (pthread_attr_t) pthread_t – opaque identifier: pthread_t pthread_self(void); int pthread_equal(pthread_t t1, pthread_t t2);

int pthread_create(pthread_t *restrict thread, const pthread_attr_t *restrict attr, void *(*start_routine)(void*), void *restrict arg);

void pthread_exit(void *value_ptr);

Thread attributes (pthread_attr_t)

pthread_t – opaque identifier:

pthread_t pthread_self(void);

int pthread_equal(pthread_t t1, pthread_t t2);

Reaping Wait equivalent (from any thread not just creator): int pthread_join(pthread_t thread, void **value_ptr); To dodge reaping: int pthread_detach(pthread_t thread); PTHREAD_CREATE_DETACHED: No need to reap (reaping would fail)

Wait equivalent (from any thread not just creator):

int pthread_join(pthread_t thread, void **value_ptr);

To dodge reaping:

int pthread_detach(pthread_t thread);

PTHREAD_CREATE_DETACHED:

No need to reap (reaping would fail)

Thread Specific Data Need some memory to appear differently to different threads Memory is keyed, key created/deleted once: int pthread_key_create(pthread_key_t *key, void (*destructor)(void*)); // before any thread uses it int pthread_key_delete(pthread_key_t key); // after all threads are done with it Destructor is thread specific To retrieve/modify memory: void *pthread_getspecific(pthread_key_t key); int pthread_setspecific(pthread_key_t key, const void *value);

Need some memory to appear differently to different threads

Memory is keyed, key created/deleted once:

int pthread_key_create(pthread_key_t *key, void (*destructor)(void*)); // before any thread uses it

int pthread_key_delete(pthread_key_t key); // after all threads are done with it

Destructor is thread specific

To retrieve/modify memory:

void *pthread_getspecific(pthread_key_t key);

int pthread_setspecific(pthread_key_t key, const void *value);

Cancelling Threads int pthread_cancel(pthread_t thread); Asynchronous not a signal Cleanup handling only (unlike signals) Order: Cancel call Cancellation point Cleanup handlers Thread-specific data destructors

int pthread_cancel(pthread_t thread);

Asynchronous

not a signal

Cleanup handling only (unlike signals)

Order:

Cancel call

Cancellation point

Cleanup handlers

Thread-specific data destructors

Cancellability: For critical sections, can't cancel int pthread_setcancelstate(int state, int *oldstate); // PTHREAD_CANCEL_ENABLE/DISABLE For control over cancel-safe points int pthread_setcanceltype(int type, int *oldtype); // PTHREAD_CANCEL_ASYNCHRONOUS/DEFERRED To place a cancellation point: void pthread_testcancel(void); Push/pop mindset, call sets on “module” entry, and restore on “module” exit

For critical sections, can't cancel

int pthread_setcancelstate(int state, int *oldstate); // PTHREAD_CANCEL_ENABLE/DISABLE

For control over cancel-safe points

int pthread_setcanceltype(int type, int *oldtype); // PTHREAD_CANCEL_ASYNCHRONOUS/DEFERRED

To place a cancellation point:

void pthread_testcancel(void);

Push/pop mindset, call sets on “module” entry, and restore on “module” exit

Cleanup Stack void pthread_cleanup_pop(int execute); void pthread_cleanup_push(void (*routine)(void*), void *arg); Execution upon: Exit Cancel Pop with non-zero execute Both in same lexical scope

void pthread_cleanup_pop(int execute);

void pthread_cleanup_push(void (*routine)(void*), void *arg);

Execution upon:

Exit

Cancel

Pop with non-zero execute

Both in same lexical scope

static RETSIGTYPE sigexit_handler(int signum) { int i; nslcd_exitsignal=signum; /* cancel all running threads */ for (i=0;i<nslcd_cfg->ldc_threads;i++) if (pthread_cancel(nslcd_threads[i])) { } } static void worker_cleanup(void *arg) { MYLDAP_SESSION *session=(MYLDAP_SESSION *)arg; myldap_session_close(session); } static void *worker(void UNUSED(*arg)) { MYLDAP_SESSION *session; /* create a new LDAP session */ session=myldap_create_session(); /* clean up the session if we're done */ pthread_cleanup_push(worker_cleanup,session); /* start waiting for incoming connections */ while (1) { /* wait for a new connection */ acceptconnection(session); } pthread_cleanup_pop(1); return NULL; } int main(int argc,char *argv[]) { ... install_sighandler(SIGTERM,sigexit_handler); install_sighandler(SIGUSR1,sigexit_handler); install_sighandler(SIGUSR2,sigexit_handler); nslcd_threads= (pthread_t *)malloc(nslcd_cfg->ldc_threads*sizeof(pthread_t)); for (i=0;i<nslcd_cfg->ldc_threads;i++) { if (pthread_create(&nslcd_threads[i],NULL,worker,NULL)) { ... exit(EXIT_FAILURE); } } for (i=0;i<nslcd_cfg->ldc_threads;i++) { if (pthread_join(nslcd_threads[i],NULL)) { ... exit(EXIT_FAILURE); } } }

Mutual Exclusion Threads are much more prone to race conditions – why? pthread_mutex_t int pthread_mutex_lock(pthread_mutex_t *mutex); int pthread_mutex_trylock(pthread_mutex_t *mutex); int pthread_mutex_unlock(pthread_mutex_t *mutex); pthread_mutex_t is strictly for mutual exclusion, not synchronization (unlike...?)

Threads are much more prone to race conditions – why?

pthread_mutex_t

int pthread_mutex_lock(pthread_mutex_t *mutex);

int pthread_mutex_trylock(pthread_mutex_t *mutex);

int pthread_mutex_unlock(pthread_mutex_t *mutex);

pthread_mutex_t is strictly for mutual exclusion, not synchronization (unlike...?)

Mutex Object: pthread_mutex Initialization: Static: pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; Non-static: int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr); int pthread_mutex_destroy(pthread_mutex_t *mutex);

Initialization:

Static:

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

Non-static:

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);

int pthread_mutex_destroy(pthread_mutex_t *mutex);

Mutex Types Type Attribute Values PTHREAD_MUTEX_DEFAULT: deadlock on double lock by same thread (fast) PTHREAD_MUTEX_RECURSIVE: no deadlock, but same # of unlocks before release PTHREAD_MUTEX_ERRORCHECK: error on double lock by same thread

Type Attribute Values

PTHREAD_MUTEX_DEFAULT: deadlock on double lock by same thread (fast)

PTHREAD_MUTEX_RECURSIVE: no deadlock, but same # of unlocks before release

PTHREAD_MUTEX_ERRORCHECK: error on double lock by same thread

RT Attributes: Protocol: PTHREAD_PRIO_NONE PTHREAD_PRIO_INHERIT: If a higher priority thread is blocked on this, execute at that its prio PTHREAD_PRIO_PROTECT: Execute at max (mine, ceiling {all my other mutexes}) Prioceiling: Highest possible priority to run at: should be > highest priority that locks this mutex

Protocol:

PTHREAD_PRIO_NONE

PTHREAD_PRIO_INHERIT: If a higher priority thread is blocked on this, execute at that its prio

PTHREAD_PRIO_PROTECT: Execute at max (mine, ceiling {all my other mutexes})

Prioceiling:

Highest possible priority to run at: should be > highest priority that locks this mutex

Futex An area in memory used for mutexing threads, atomic operations Futex system call in contended cases By mmapping this (MMAP_SHARED), we have full kernel support, thus Sharing Attribute

An area in memory used for mutexing threads, atomic operations

Futex system call in contended cases

By mmapping this (MMAP_SHARED), we have full kernel support, thus

Sharing Attribute

Another Mutex Object: Read/Write Locks Multiple concurrent readers only one writer allowed (Lock state) Attributes: sharing Read: int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock); int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock); Write: int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock); int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock); Unlock: int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);

Multiple concurrent readers

only one writer allowed (Lock state)

Attributes: sharing

Read:

int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);

int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);

Write:

int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);

int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);

Unlock:

int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);

Condition Variables Synchronization pthread_cond_t cond = PTHREAD_COND_INITIALIZER; Attributes: sharing Always mutexed (why?) Implicit cancellation point – upon cancel, do not consume int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t mutex); Atomically: release mutex and wait on condition, acquired on wakeup int pthread_cond_broadcast(pthread_cond_t *cond); // all Int pthread_cond_signal(pthread_cond_t *cond); // at least one

Synchronization

pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

Attributes: sharing

Always mutexed (why?)

Implicit cancellation point – upon cancel, do not consume

int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t mutex);

Atomically: release mutex and wait on condition, acquired on wakeup

int pthread_cond_broadcast(pthread_cond_t *cond); // all

Int pthread_cond_signal(pthread_cond_t *cond); // at least one

static void PushMessage (WMMsgQueuePtr pQueue, WMMsgNodePtr pNode) { /* Lock the queue mutex */ pthread_mutex_lock (&pQueue->pmMutex); pNode->pNext = NULL; if (pQueue->pTail != NULL) { pQueue->pTail->pNext = pNode; } pQueue->pTail = pNode; if (pQueue->pHead == NULL) { pQueue->pHead = pNode; } /* Increase the count of elements in the queue by one */ ++g_nQueueSize; /* Release the queue mutex */ pthread_mutex_unlock (&pQueue->pmMutex); /* Signal that the queue is not empty */ pthread_cond_signal (&pQueue->pcNotEmpty); } static WMMsgNodePtr PopMessage (WMMsgQueuePtr pQueue, WMInfoPtr pWMInfo) { /* Lock the queue mutex */ pthread_mutex_lock (&pQueue->pmMutex); /* Wait for --- */ while (pQueue->pHead == NULL) { pthread_cond_wait (&pQueue->pcNotEmpty, &pQueue->pmMutex); } pNode = pQueue->pHead; if (pQueue->pHead != NULL) { pQueue->pHead = pQueue->pHead->pNext; } if (pQueue->pTail == pNode) { pQueue->pTail = NULL; } /* Drop the number of elements in the queue by one */ --g_nQueueSize; /* Release the queue mutex */ pthread_mutex_unlock (&pQueue->pmMutex); return pNode; }

Process vs Thread Ease of communication Creation overhead Potential for race conditions Vulnerability coupling SMP systems

Ease of communication

Creation overhead

Potential for race conditions

Vulnerability coupling

SMP systems

Add a comment

Related pages

SysProg - aktuell

(Abgabe spätestens: 14.12.2012) 3.Übungsblatt : Funktionsmuster (Abgabe spätestens: 11.01.2013) 4.Übungsblatt: Funktionsmuster: Selbstprüfmuster
Read more

Frontpage WAVV 2014 - pi-sysprog.de

Here are PDFs of the original presentation. Sorry some of the animations are gone. CICS - Using the XMLparser beyond the standard IESSOAP implementation
Read more

Handbuch für für Caddy 14 D 95 PS - VW Caddy Forum ...

sysprog 2010-11-22 14:05:14 UTC #1. gibt es ein Handbuch für Caddy 14 D sollte Motoreinstellung überprüfen springt wenn er warm sehr schlecht an ...
Read more

Linux/Unix Systemprogrammierung - sakuranohana.org

Einfuhr¨ ung ¨Uberblick ub¨ er SysProg. Einfuhr¨ ung in ANSI-C Standard I/O-Funktionen Linux/Unix Systemprogrammierung ... August 14, 2006
Read more

THM | Campus Gießen | Wiesenstraße 14 | FB MNI | 35390 ...

THM | Campus Gießen | Wiesenstraße 14 | FB MNI | 35390 Gießen University of Applied Sciences Fachbereich MNI An den Dekan des FB MNI ... SysProg, durch ...
Read more

www.ifmt.b-tu.de

10;10 1;2;3;4;5;6;7;8;9;10 2;3;4;5;6;7;8;9;10;11 3;4;5;6;7;8;9;10;11;12 4;5;6;7;8;9;10;11;12;13 5;6;7;8;9;10;11;12;13;14 6;7;8;9;10;11;12;13;14;15 7;8;9;10 ...
Read more

Informatik 4 im Bachelor Curriculum

Informatik 4 im Bachelor Curriculum SysInf 6LP SysProg 6LP KiVS 6LP ReSi 6LP SDF 6LP PG BA-Arbeit Vi t 0 lFli 6Variante 0, vgl. Folie 6: Module der ...
Read more

Ñ.Ë.Òðîøèí ... - sysprog.info

287 ! " ! # ! ! $ % % $& ! " # ! ' (! $ ) *) " $ ! " +, ) $ )- владелец множества 1- ый
Read more