C: protecting a shared counter with a POSIX mutex

POSIX threads (pthreads) let one C program run several threads in the same address space. They share global variables, which is powerful and dangerous. counter++ is a load, an add, and a store, so two threads can interleave and lose updates. Unsynchronized access is a data race, and in C it is undefined behaviour.

C
#include <pthread.h>
#include <stdio.h>

static int counter = 0;
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

static void *work(void *arg) {
  (void)arg;
  for (int i = 0; i < 100000; i++) {
    pthread_mutex_lock(&lock);
    counter++;
    pthread_mutex_unlock(&lock);
  }
  return NULL;
}

int main(void) {
  pthread_t a, b;
  pthread_create(&a, NULL, work, NULL);
  pthread_create(&b, NULL, work, NULL);
  pthread_join(a, NULL);
  pthread_join(b, NULL);
  printf("counter=%d\n", counter);
  return 0;
}
Read the full lesson