Overview

This section covers more advanced synchronization tools, focusing on Semaphores, Monitors, and Classical Synchronization Problems such as the Bounded-Buffer Problem and Dining-Philosophers Problem. The notes include examples implemented in C where appropriate.

Topics Covered:

  1. Semaphores
  2. Deadlock and Starvation
  3. Monitors
  4. Condition Variables
  5. Classical Synchronization Problems

Semaphores

A semaphore is a synchronization tool that allows processes to coordinate their execution. Unlike mutex locks, semaphores can be used to manage access to shared resources or synchronize processes without necessarily accessing shared data.

Key Concepts:

Example of Semaphore Operations:

wait(S) {
    while (S <= 0); // busy wait
    S--;
}

signal(S) {
    S++;
}

Types of Semaphores:

  1. Binary Semaphore: The semaphore value can only be 0 or 1, making it behave similarly to a mutex lock.
  2. Counting Semaphore: The semaphore value can range over an unrestricted domain, typically used to control access to multiple instances of a resource.

Example in C:

#include <semaphore.h>
#include <stdio.h>

sem_t sem;  // Declare a semaphore

int main() {
    // Initialize the semaphore
    if (sem_init(&sem, 0, 1) != 0) {
        printf("Error initializing semaphore\\\\n");
        return 1;
    }

    // Acquire the semaphore
    sem_wait(&sem);

    // Critical Section
    printf("In critical section\\\\n");

    // Release the semaphore
    sem_post(&sem);

    // Destroy the semaphore
    sem_destroy(&sem);

    return 0;
}