1
votes

I have questions about pthread_cond_signal and pthread_cond_wait. For example, in the code below, According to my understanding, when inc_count calls pthread_cond_signal, count += 125 in watch_count can be executed only after count_mutex is unlocked in inc_count.

The count_mutex was unlocked in watch_count when pthread_cond_wait executed and only gets locked after pthread_mutex_unlock in inc_count is executed. Am I right?

void *inc_count(void *t) 
{
    int i;
    long my_id = (long)t;

    for (i = 0; i < TCOUNT; i++) 
    {
        pthread_mutex_lock(&count_mutex);
        count++;

        if (count == COUNT_LIMIT) 
        {
            pthread_cond_signal(&count_threshold_cv);
        }

        pthread_mutex_unlock(&count_mutex);
    }

    pthread_exit(NULL);
}

void *watch_count(void *t) 
{
    long my_id = (long)t;

    pthread_mutex_lock(&count_mutex);
    while (count < COUNT_LIMIT)
    {
        pthread_cond_wait(&count_threshold_cv, &count_mutex);
        count += 125;
    }

    pthread_mutex_unlock(&count_mutex);
    pthread_exit(NULL);
}
2

2 Answers

5
votes

pthread_cond_wait() unlocks the mutex on entry and locks it again on exit. If another thread acquires the lock during that time, pthread_cond_wait() cannot return until that other thread has released the lock.

So, if watch_count() is blocked in pthread_cond_wait(), and inc_count() runs and calls pthread_cond_signal(), then watch_count() will not return from pthread_cond_wait() until inc_count() has called pthread_mutex_unlock().

However, pthread_cond_wait() can wake even if not signalled. This is called a spurious wake-up. watch_count() can therefore execute count+=125 many times, even if inc_count() never runs, or never calls pthread_cond_signal().

0
votes

count += 125 in watch_count can be executed only after count_mutex is unlocked in inc_count

Yes.

The count_mutex was unlocked in watch_count when pthread_cond_wait executed and only gets locked after pthread_mutex_unlock in inc_count is executed.

Yes, in the sense that when pthread_cond_wait returns watch_count holds the mutex, and thus it will only return after inc_count has unlocked the mutex. (Provided COUNT starts out below COUNT_LIMIT when the while is first reached..)

BTW: This code hurts my head a little. I really wouldn't recommend modifying count in watch_count as the control flow could get hard to figure out if you ever have more than one thread running that function and you start to use pthread_cond_broadcast.