Semaphores for Ordering

This lesson discusses another use case of semaphores, as a way for ordering events in concurrent programs.

We'll cover the following...

Semaphores are also useful to order events in a concurrent program. For example, a thread may wish to wait for a list to become non-empty, so it can delete an element from it. In this pattern of usage, we often find one thread waiting for something to happen, and another thread making that something happen and then signaling that it has happened, thus waking the waiting thread. We are thus using the semaphore as an ordering primitive (similar to our use of condition variables earlier).

A simple example is as follows. Imagine a thread creates another thread and then wants to wait for it to complete its execution.

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>

#include "common.h"
#include "common_threads.h"

sem_t s;

void *child(void *arg) {
    sleep(2);
    printf("child\n");
    sem_post(&s); // signal here: child is done
    return NULL;
}

int main(int argc, char *argv[]) {
    sem_init(&s, 0, X); 
    printf("parent: begin\n");
    pthread_t c;
    Pthread_create(&c, NULL, child, NULL);
    sem_wait(&s); // wait here for child
    printf("parent: end\n");
    return 0;
}
A Parent Waiting For Its Child

When this program runs, we would like to see the ...