110 likes | 127 Views
Learn about Pthread API, thread creation, completion, locks, condition variables, and how to ensure safe code execution in C programming with examples.
E N D
Interlude: Thread API Joonmin Jeon(lsleard@snu.ac.kr) School of Computer Science and Engineering Seoul National University
Pthread API • POSIX standard for thread API • It is defined in <pthread.h> header • It consists of several routine group • Thread Routines • Attribute Object Routines • Mutex Routines • Condition Variable Routines • Read/Write Lock Routines • Per-Thread Context Routines • Cleanup Routines
Thread Creation #include<pthread.h> int pthread_create( pthread_t * thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void * arg); • pthread_create API takes 4 arguments • thread_t type thread to identify created thread • thread_attr_t type attr to give some attribute thread • function pointer to actual running function in thread • void pointer to use as argument of running function • to allows any types of variable, argument type and return type of runner function is void *
Thread Completion • Thread is terminated in one of following way • It calls pthread_exit() • It returns from start_routine() • It is canceled by calling thread_cancel() • Any of the thread in the process calls exit() • Using pthread_join() For wait a thread to complete
Thread Completion #include <stdio.h> #include <pthread.h> typedef struct __myarg_t { int a; int b; } myarg_t; typedef struct __myret_t { int x; int y; } myret_t; void *mythread(void *arg){ myarg_t *m = (myarg_t *)arg; printf("argument %d %d\n", m->a, m->b); myret_t *r = malloc(sizeof(myret_t)); r->x = 1; r->y =2; return (void *) r; } int main(void){ pthread_t p; myret_t *m; myarg_t arg; arg.a=10, arg.b=20; pthread_create(&p, NULL, mythread, &args); pthread_join(p, (void **) &m); printf("returned %d %d\n", m->x, m->y); return 0; } Output Argument 10 20 Returned 1 2 Make sure that return address valid Thread stack is destroyed when terminate thread
Locks PTHREAD_MUTEX_INITIALIZER; int pthread_mutex_init(pthread_mutext_t *mutex, pthread_mutexattr_t *attr ); int ptrhead_mutex_destroy(pthread_mutex_t *mutex ); int pthread_mutex_lock(pthread_mutex_t *mutex ); int pthread_mutex_trylock(pthread_mutex_t *mutex ); int pthread_mutex_timedlock(pthread_mutex_t *mutex, struct timespec *abs_timeout ); int pthread_mutex_unlock(pthread_mutex_t *mutex ); • Providing mutual exclusion to a critical section • Initializing APIs • Destroying API • Acquiring APIs • Releasing API
Condition Variables PTHREAD_COND_INITIALIZER; int pthrad_cond_init(pthread_cond_t *cond, pthrad_condattr_t *attr); int pthread_cond_wait(pthrad_cond_t *cond, pthread_mutext_t *mutex); int pthread_cond_signal(pthread_cond_t *cond); • It is Useful when some kind of signaling must take place between thread • To avoid race condition, lock must be held before signaling or waiting • Initializing APIs • Waiting API • Signaling API
Condition Variables int main(void){ pthread_t p1, p2; pthread_create(&p2, NULL, phase2, NULL); pthread_create(&p1, NULL, phase1, NULL); pthread_join(p2, NULL); return 0; } pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t cond = PTHREAD_COND_INITIALIZER; int ready = 0; void *phase1(void *arg){ printf("phase1 start\n"); printf("phase1\n"); pthread_mutex_lock(&lock); ready = 1; pthread_cond_signal(&cond); pthread_mutex_unlock(&lock); printf("phase1 end\n"); return NULL; } void *phase2(void *arg){ printf("phase2 start\n"); pthread_mutex_lock(&lock); while(ready == 0) pthread_cond_wait(&cond, &lock); pthread_mutex_unlock(&lock); printf("phase2\n"); printf("phase2 end\n"); return NULL; } CASE 1 Output, p1 runs first phase1 start phase2 start Phase1 phase1 end Phase2 phase2 end CASE 2 Output, p2 runs first phase2 start phase1 start Phase1 phase1 end Phase2 phase2 end
Wrapper void Pthread_mutex_lock(pthread_mutex_t *mutex){ int rc = pthread_mutex_lock(mutex); assert(rc == 0); } Assert that the routine succeeded Example of Wrapper
Compiling and Running prompt> gcc -o main main.c -Wall -pthread Include the header pthread.h to the code file Adding the -pthread flag to linker command Example of compile command
Summary POSIX Thread – Pthread API Creating and Completing Thread Building mutual exclusion via locks Signaling and waiting via condition variables Wrapping code to ensure safe Compiling and running