chapter 30: Condition Variables Flashcards
why do we need condition variables?
there are many cases where a thread wishes to check whether a condition is true before proceeding
parent waiting for child: spin based approach
this is bad. grossly inefficient
what is a condition variable?
a CV is an explicit queue that threads can put themselves on when some condition is not as desired.
by waiting for the condition, when state changes can then wake up
what are the 2 main calls from a CV?
wait() : when thread wishes to put itself to sleep
signal() : when thread has changed state in the program and wants to wake a sleeping thread waiting on its condition.
wait and signal function calls
pthread_cond_wait(pthread_cond_t *c, pthread_mutex_t *m)
pthread_cond_signal(pthread_cond_t *c)
wait takes cv and mutex - releases the lock and put the thread to slepp
signal takes cv - re-aquire lock
parent waiting for child: using a condition variable
parent creates child
case 1: parent waits, child sets done to 1 and signals parents to wake up when its done.
case 2: child runs first, sets done to 1 and signals(but there is no thread). parents then run and sees done is 1 so then no need to wait.
can this be done without variable done or locks
no.
without done, consider case 2: parent will simply call and be stuck forever with no child to wake it.
without locks, consider case 1: just before parent calls wait to go to sleep, it gets interrupted(no locks) child runs changes the state to 1 and signals, no thread is waiting. when parent wakes and sleeps it sleeps forever.
Tip: Always hold the lock while signalling and wait
HOLD IT
what is the main problem that cv solves?
consumer/producer problem
what is mesa semantics and hoare semantic
mesa - while loop
hoare - if statement
1st example: 1cv and 1 if. why is this bad
consumer 2 sneaks in and takes the buffer.
we cant guarantee that after consumer 1 wakes, the state will always be the same. this is why WHILE loop is so important. it re-checks the state. making sure consumer 1 will not try to get from empty buffer.
2nd example: single cv and While. why is this bad
single cv is the problem here.
producer wakes consumer 1 only
consumer 1 consumes the buffer and now has to signal to wake one of the threads up. IF it wakes consumer 2, he will wake and see the buffer is empty and sleep. Now ALL 3 threads are asleep.
solution to example 2, have 2 CVs.
one for empty and one for fill
the producer wait on the condition empty, and signals fill
the consumers wait on fill and signals empty
by doing so, a consumer can never wake a consumer and a producer can never wake a producer
final solution: 2 CVs and while
a producer only sleeps if all buffers are currently filled
a consumer only sleeps if all buffers are currently empty
what does pthread_cond_broadcast() do?
it wakes up all waiting threads
negative: might needlessly wake up many threads