21CS 2109AA
Operating Systems
Thread API
© 2022 KL University – The contents of this presentation are an intellectual and copyrighted property of KL University. ALL RIGHTS RESERVED 1
Thread API
• int pthread_create (pthread_t* thread, const pthread_attr_t * attr,
void* (*start_routine)(void*), void* arg)
• int pthread_join(pthread_t thread, (void *)*value_ptr)
• int pthread_mutex_lock(pthread_mutex_t *mutex)
• int pthread_mutex_unlock(pthread_mutex_t *mutex)
• int pthread_mutex_trylock(pthread_mutex_t *mutex)
• int pthread_mutex_timelock(pthread_mutex_t *mutex,
struct timespec *abs_timeout);
• int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t
*mutex)
• int pthread_cond_signal(pthread_cond_t *cond)
© 2022 KL University – The contents of this presentation are an intellectual and copyrighted property of KL University. ALL RIGHTS RESERVED 2
Thread Creation
How to create and control
threads?#include <pthread.h>
int
pthread_create( pthread_t* thread,
const pthread_attr_t* attr,
void*
(*start_routine)(void*),
void* arg);
•thread: Used to interact with this thread (OUT).
•attr: Used to specify any attributes this thread might have.
• ¢ Stack size, Scheduling priority, … (IN)
• start_routine: the function this thread start running in (IN)
• arg: the argument to be passed to the function (start routine) (IN)
• ¢ a void pointer allows us to pass in any type of argument.
• Returns 0 if went good (a error code otherwise)
© 2022 KL University – The contents of this presentation are an intellectual and copyrighted property of KL University. ALL RIGHTS RESERVED 3
Thread Creation (Cont.)
If start_routine instead required another type argument, the
declaration would look like this (example):
An integer argument:
int
pthread_create(…, // first two args are the same
void*
(*start_routine)(int), int
Input is anything (usually a arg);
pointer to struct for multiple
arguments or even internal returns), return an integer:
int
pthread_create(…, // first two args are the same
int
(*start_routine)(void*),
void*
arg);
© 2022 KL University – The contents of this presentation are an intellectual and copyrighted property of KL University. ALL RIGHTS RESERVED 4
Wait for a thread to complete
int pthread_join(pthread_t thread, (void *)*value_ptr);
thread: Specify which thread to wait for
value_ptr: A pointer we want to put the return value of the start routine
¢ Because pthread_join() routine changes the value, you need
to pass in a pointer to that value.
Returns 0 if good, or EINVAL if err
© 2022 KL University – The contents of this presentation are an intellectual and copyrighted property of KL University. ALL RIGHTS RESERVED 5
Example-1 (thread1.c)
#include <stdio.h> pthread_create(&p1, NULL, mythread,
#include <stdlib.h> "A");
#include <pthread.h> pthread_create(&p2, NULL, mythread,
"B");
void * mythread(void *arg) {
pthread_join(p1, NULL);
printf(" Thread : %s\n", (char *) arg);
pthread_join(p2, NULL);
return NULL;
printf("main: end\n");
}
return 0;
int main(int argc, char *argv[])
}
{
pthread_t p1, p2;
printf("main: begin\n");
© 2022 KL University – The contents of this presentation are an intellectual and copyrighted property of KL University. ALL RIGHTS RESERVED 6
Example: Simpler Argument Passing to
a Thread
Just passing in a single value
#include <stdio.h>
#include <pthread.h>
void * hello(void *input) {
printf("%s\n", (char *)input);
pthread_exit(NULL);
}
int main(void) {
pthread_t tid;
pthread_create(&tid, NULL, hello, "hello world");
pthread_join(tid, NULL);
return 0; }
© 2022 KL University – The contents of this presentation are an intellectual and copyrighted property of KL University. ALL RIGHTS RESERVED 7
Locks
Provide mutual exclusion to a critical
section
Interface
int pthread_mutex_lock(pthread_mutex_t *mutex); int
pthread_mutex_unlock(pthread_mutex_t *mutex);
Usage (w/o lock initialization and error
check)
pthread_mutex_t lock;
pthread_mutex_lock(&lock);
x = x + 1; // or whatever your critical section is
pthread_mutex_unlock(&lock);
No other thread holds the lock à the thread will acquire the lock and
enter the critical section.
If another thread hold the lock à the thread will not return from the call
until it has acquired the lock.
© 2022 KL University – The contents of this presentation are an intellectual and copyrighted property of KL University. ALL RIGHTS RESERVED 8
All locks must be properly initialized (i.e. unlocked
value).
One way: using PTHREAD_MUTEX_INITIALIZER
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
The dynamic way: using pthread_mutex_init()
int rc = pthread_mutex_init(&lock, NULL);
assert(rc == 0 && “Error in mutex
init”);
© 2022 KL University – The contents of this presentation are an intellectual and copyrighted property of KL University. ALL RIGHTS RESERVED 9
Case Study
Create 2 Threads such that they count up to 10000 each.
So the Total Count by the 2 Threads must be =20000
(10000+10000).
(thread3.c using mutex)
© 2022 KL University – The contents of this presentation are an intellectual and copyrighted property of KL University. ALL RIGHTS RESERVED 10
Thread3.c
#include <stdio.h>
#include <stdlib.h> int main(int argc, char *argv[])
#include <pthread.h> { pthread_t p1, p2;
pthread_mutex_t mutex1 = printf("\n main: begin ");
PTHREAD_MUTEX_INITIALIZER; pthread_create(&p1, NULL, mythread, "A");
int counter = 0;
pthread_create(&p2, NULL, mythread, "B");
int max=10000; pthread_join(p1, NULL);
void * mythread(void *arg)
pthread_join(p2, NULL);
{ int i; // stack (private per thread)
pthread_mutex_lock( &mutex1 ); printf("\n main: done");
for (i = 0; i < max; i++) { printf("\n Counter value:%d",counter);
counter = counter + 1; } printf("\n Actual Counter Value:%d",max*2);
printf("\n Thread %s: done", (char *)arg); return 0;
pthread_mutex_unlock( &mutex1 );
}
return NULL; }
© 2022 KL University – The contents of this presentation are an intellectual and copyrighted property of KL University. ALL RIGHTS RESERVED 11
Compile and Run
prompt> gcc thread3.c –lpthread
prompt> ./a.out
Note :
Run the same program ‘n’(10-20) number of times
and observe the result
(Counter Value and Actual Value)
Analyze the Output !
© 2022 KL University – The contents of this presentation are an intellectual and copyrighted property of KL University. ALL RIGHTS RESERVED 12
Locks Acquisition
These two calls are also used in lock acquisition
int pthread_mutex_trylock(pthread_mutex_t *mutex); int
pthread_mutex_timelock(pthread_mutex_t *mutex,
struct timespec *abs_timeout);
trylock: return failure if the lock is already held
timelock: return after a timeout or after acquiring the
lock
© 2022 KL University – The contents of this presentation are an intellectual and copyrighted property of KL University. ALL RIGHTS RESERVED 13
Condition Variables
Condition variables are useful when some kind of signaling must
take place between threads.
int pthread_cond_wait(pthread_cond_t *cond,
pthread_mutex_t *mutex);
int pthread_cond_signal(pthread_cond_t *cond);
pthread_cond_wait:
¢ Put the calling thread to sleep.
¢ Wait for some other thread to signal it.
pthread_cond_signal:
¢ Unblock at least one of the threads that are blocked on the condition
variable
© 2022 KL University – The contents of this presentation are an intellectual and copyrighted property of KL University. ALL RIGHTS RESERVED 14
A thread calling wait routine:
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t init = PTHREAD_COND_INITIALIZER;
pthread_mutex_lock(&lock); while
(initialized == 0)
pthread_cond_wait(&init, &lock);
pthread_mutex_unlock(&lock);
The wait call releases the lock when putting said caller to sleep.
Before returning after being woken, the wait call re-acquire the
lock.
`
pthread_mutex_lock(&lock);
initialized = 1;
pthread_cond_signal(&init);
pthread_mutex_unlock(&lock);
© 2022 KL University – The contents of this presentation are an intellectual and copyrighted property of KL University. ALL RIGHTS RESERVED 15
© 2022 KL University – The contents of this presentation are an intellectual and copyrighted property of KL University. ALL RIGHTS RESERVED 16