160 likes | 290 Views
Threads and Thread Control. Thread Concepts Pthread Creation and Termination Pthread synchronization Threads and Signals. Overview. Threads are concurrent lines of execution within a process. Sometimes called “lightweight processes”
E N D
Threads and Thread Control • Thread Concepts • Pthread Creation and Termination • Pthread synchronization • Threads and Signals
Overview • Threads are concurrent lines of execution within a process. Sometimes called “lightweight processes” • All the threads of a process are in its memory space, but each thread has its own • Thread ID • Stack • Register values • Set of blocked and pending signals • Thread specific data • errno variable • There also must be a scheduling policy for thread execution
Overview • A typical UNIX process contains only a single thread of execution • Multiple threads allow us to take advantage of parallel programming without the overhead of a new process • May make programming for asynchronous events easier
POSIX Threads • pthreads are the optional POSIX standardization for threads • Must include <pthread.h> and link against the pthread library • -lpthread when compiling a C/C++ program
Thread Identification • Each thread has an identifier • Only unique within the process to which the thread belongs • IDs can be represented by pthread_t which can be a struct • Implementation of struct is system dependant • A thread can get its own ID structure withpthread_t pthread_self(void); • Compare two thread IDs with int pthread_equal(pthread_t t1, pthread_t t2);
Thread Creation int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg); • Arguments • thread points to the new thread ID • pthread_attr_t set of thread attributes. Use NULL for default attributes • start_routine is a function pointer to the function that the new thread will begin executing when it is created • arg is the single argument that may be passed to the start routine. If you need to pass multiple parameters, bundle them as a struct and pass that
Thread Termination • If any thread calls exit, _exit or Exit, the entire process will terminate • Thread may terminate due to exec • 3 ways a single thread can terminate • Return from the start routine • Call pthread_exitvoid pthread_exit(void *value_ptr); • Thread cancelled by another thread withint pthread_cancel(pthread_t thread);
Joining and Detaching int pthread_join(pthread_t thread, void **value_ptr); int pthread_detach(pthread_t thread); • Join is similar to waitpid. Allows a thread to wait on another to terminate • Termination status of thread waited on returned in value_ptr if specified in call to pthread_exit • pthread_detach allows us to put a thread in the detached state
Joinable Attribute • We can specify that a newly created thread is joinable or detached when we create the thread with the pthread_attr_t parameter • Threads created as detached can not be joined • Default is joinable • Detached thread resources are released as soon as thread terminates • Creating a thread as detached prevents synchronization (since we can’t join it)
Mutexes • Mutex – “mutual exclusion” • Only one thread at a time can own a particular mutex variable • A thread aquires the mutex by “locking” it. When it is done, it releases it by “unlocking” it • Mutex variable is of type pthread_mutex_t
Mutexes int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr); • mutex is a pointer to a variable of type pthread_mutex_t • attr is a pointer to a type that holds attributes for non default mutexes. We can pass in NULL for a default mutex
Mutex Use • Declare mutex variable • pthread_mutex_t myMutex; • Initialize • pthread_mutex_create(&myMutex, NULL); • A thread locks the mutex • pthread_mutex_lock(&myMutex); • Thread executes critical section and then releases the mutext • pthread_mutex_unlock(&myMutex); • When mutex not longer needed, it can be destroyed • pthread_mutex_destroy(&myMutex);
Condition Variables • Allows threads to synchronize based on value of data • Avoids busy loop where threads acquire lock, check value of a variable and repeat until the value changes • Condition variables should always be protected by mutex locks
Condition Variables int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr); int pthread_cond_destroy(pthread_cond_t *cond); int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t * mutex); int pthread_cond_broadcast(pthread_cond_t *cond); • Notify all threads waiting on this condition int pthread_cond_signal(pthread_cond_t *cond); • Notify a single thread waiting on this condition • See page 384-385 for example
Threads and Signals • Signals are delivered to a single thread • If signal is the result of hardware fault, it is usually sent to the thread that caused it • Otherwise signal sent to arbitrary thread • Each thread has its own signal mask int pthread_sigmask(int how, const sigset_t *set, sigset_t *oset); • Signal dispositions shared between all threads in a process
Threads and Signals int sigwait(const sigset_t *set, int *sig); • Allows a thread to wait for a signal from the set given by set parameter • The particular signal received is returned through the sig parameter • To prevent race condition, the signal being waited on must be blocked before calling this function int pthread_kill(pthread_t thread, int sig); • Sends a signal to a specified thread