Synchronization in C

Prev: Synchronization in Python Next: Cleaning up Python threads

Mutual exclusion

The child threads run:

void child_code(Shared *shared)
{
  while (1) {
    if (shared->counter >= shared->end) {
      return;
    }
    shared->array[shared->counter]++;
    shared->counter++;
  }
}

The goal is that each element of array should be incremented exactly once.

Exercise

Use semaphores to enforce exclusive access to the shared variables and run the program again to confirm that there are no errors.

Make your own semaphores

Exercise

Read about mutexes and condition variables, and then use them to write an implementation of semaphores.

The book provides wrappers like these:

typedef pthread_mutex_t Mutex;
typedef pthread_cond_t Cond;

along with helper functions for make_mutex(), mutex_lock(), mutex_unlock(), make_cond(), cond_wait(), and cond_signal().

Follow-up

Given this implementation:

void sem_wait(Semaphore *semaphore)
{
  mutex_lock(semaphore->mutex);
  semaphore->value--;
 
  if (semaphore->value < 0) {
    do {
      cond_wait(semaphore->cond, semaphore->mutex);
    } while (semaphore->wakeups < 1);
    semaphore->wakeups--;
  }
  mutex_unlock(semaphore->mutex);
}
 
void sem_signal(Semaphore *semaphore)
{
  mutex_lock(semaphore->mutex);
  semaphore->value++;
 
  if (semaphore->value <= 0) {
    semaphore->wakeups++;
    cond_signal(semaphore->cond);
  }
  mutex_unlock(semaphore->mutex);
}

Why can’t we replace the do...while loop with a while loop?