Teflondre
Teflondre

Reputation: 21

Understanding semaphores with pthreads (code included)

So in class, we learned about semaphores and stuff and our professor let us know that this code below would be handy to learn for our exam. Unfortunately our exam is on Friday, and whole list of excuses, i just need to be able to understand this code for the exam and for future cases. I understand that the mutex_t is a lock system and the cond_t is a condition system in which signals get passed through sema_P and sema_V (if the value is 0, race condition occurs and the thread is locked out by cond_wait until another thread increases the value and is unlocked by cond_signal), but why does a lock need to get passed around? Why is there a mutex_lock and mutex_unlock in both decrementer P() and incrementer V()? How does this work with the threads and the conditions (cont_t)?

typedef struct
{
        pthread_mutex_t lock;
        pthread_cond_t wait;
        int value;
} sema;

void pthread_sema_init(sema *s, int count)
{
        s->value = count;
        pthread_cond_init(&(s->wait),NULL);
        pthread_mutex_init(&(s->lock),NULL);
        return;
}

void pthread_sema_P(sema *s)
{
        pthread_mutex_lock(&(s->lock));
        s->value--;
        if(s->value < 0) {
                pthread_cond_wait(&(s->wait),&(s->lock));
        }
        pthread_mutex_unlock(&(s->lock));
        return;
}

void pthread_sema_V(sema *s)
{

        pthread_mutex_lock(&(s->lock));
        s->value++;
        if(s->value <= 0) {
                pthread_cond_signal(&(s->wait));
        }
        pthread_mutex_unlock(&(s->lock));
}

Upvotes: 0

Views: 269

Answers (1)

caf
caf

Reputation: 239241

The mutex sema.lock is there to protect the shared variable sema.value, ensuring that only one thread accesses that value at a time. Both pthread_sema_P() and pthread_sema_V() must take the lock because they both access sema.value.

That implementation of sempahores is buggy, by the way - it doesn't handle spurious wakeups (a "spurious wakeup" is where pthread_cond_wait() wakes up despite not being signalled - this is allowed by the spec).

A more traditional implementation might be:

void pthread_sema_P(sema *s)
{
        pthread_mutex_lock(&s->lock);
        while (s->value < 1) {
                pthread_cond_wait(&s->wait, &s->lock);
        }
        s->value--;
        pthread_mutex_unlock(&s->lock);
}

void pthread_sema_V(sema *s)
{
        pthread_mutex_lock(&s->lock);
        s->value++;
        pthread_cond_signal(&s->wait);
        pthread_mutex_unlock(&s->lock);
}

Upvotes: 0

Related Questions