c - Condition variables and mutex_unlock -
code:
void *inc_func(void *arg) { pthread_mutex_lock(&mutex); pthread_cond_signal(&count_threshold_cv); sleep(1); pthread_mutex_unlock(&mutex); } void *watch(void *arg) { pthread_mutex_lock(&mutex); pthread_cond_wait(&count_threshold_cv,&mutex); sleep(1); pthread_mutex_unlock(&mutex); } int main() { pthread_t id[2]; pthread_create(&id[0],null,watch,null); pthread_create(&id[1],null,inc_func,null); int i; for(i=0;i<2;i++) pthread_join(id[i],null); }
now have 1 mutex_unlock
function executed in each thread. , 1 locked mutex. why doesn't lead undefined behaviour
. since both threads try unlock same mutex leads 1 trying unlock unlocked mutex.
edit: pthread_cond_wait
releases mutex
second thread use. consider second thread executes pthread_cond_signal
leads first thread reacquire mutex
. have 2 threads having same mutex
lock,because both didn't execute mutex_unlock
because of 'sleep' function. understanding wrong?
pthread_mutex_lock()
blocks if mutex locked locked. returns if mutex got unlocked.pthread_cond_wait()
unlocks mutex when starting wait , locks before returning. returning might delayed if mutex in question still locked. returning delay until mutex got unlocked.
putting above , applying code show 1 sees each thread function nicely starts locking followed unlocking (and on), fine.
referring example code: pthread_cond_wait()
returns when inc_func()
had called pthread_mutex_unlock()
.
to handle scenario described example code need consider 2 special cases
- the case of signal coming first and
- the case of called "spurious wake-ups",
pthread_cond_wait()
returning without having been signalled.
to handle both such case each condition should have watch variable.
pthread_mutex_t mutex = ... pthread_cond_t count_threshold_cv = ... int signalled = 0; void *inc_func(void *arg) { pthread_mutex_lock(&mutex); pthread_cond_signal(&count_threshold_cv); signalled = 1; pthread_mutex_unlock(&mutex); } void *watch(void *arg) { pthread_mutex_lock(&mutex); while (0 == signalled) { pthread_cond_wait(&count_threshold_cv,&mutex); } pthread_mutex_unlock(&mutex); } int main(void) { pthread_t id[2]; pthread_create(&id[0],null,watch,null); pthread_create(&id[1],null,inc_func,null); int i; for(i=0;i<2;i++) pthread_join(id[i],null); }
Comments
Post a Comment