Generic selectors
Exact matches only
Search in title
Search in content
Post Type Selectors

Write a Semaphore solution for dining Philosopher’s problem?

The dining philosophers problem is a classic concurrency problem in computer science, which involves a group of philosophers who share a circular table and some chopsticks. Each philosopher alternates between thinking and eating, but they can only eat when they have two chopsticks. If all philosophers try to grab a chopstick at the same time, they may deadlock and none of them will be able to eat.

One solution to the dining philosophers problem is to use semaphores, which are a type of synchronization primitive that allows multiple threads to access a shared resource while preventing race conditions and other synchronization problems.

Here’s an example solution that uses semaphores:

// define the number of philosophers and chopsticks
#define NUM_PHILOSOPHERS 5
#define NUM_CHOPSTICKS NUM_PHILOSOPHERS

// create an array of semaphores to represent the chopsticks
Semaphore chopstick[NUM_CHOPSTICKS];

// create an array of threads to represent the philosophers
Thread philosopher[NUM_PHILOSOPHERS];

// define a function to simulate a philosopher's behavior
void philosopher_behavior(int id) {
    while (true) {
        // think for a while
        think();

        // pick up the left chopstick
        chopstick[id].wait();

        // pick up the right chopstick
        chopstick[(id + 1) % NUM_CHOPSTICKS].wait();

        // eat for a while
        eat();

        // put down the right chopstick
        chopstick[(id + 1) % NUM_CHOPSTICKS].signal();

        // put down the left chopstick
        chopstick[id].signal();
    }
}

// initialize the semaphores and start the threads
int main() {
    // initialize the chopstick semaphores
    for (int i = 0; i < NUM_CHOPSTICKS; i++) {
        chopstick[i] = Semaphore(1);
    }

    // start the philosopher threads
    for (int i = 0; i < NUM_PHILOSOPHERS; i++) {
        philosopher[i] = Thread(philosopher_behavior, i);
    }

    // wait for the philosopher threads to finish
    for (int i = 0; i < NUM_PHILOSOPHERS; i++) {
        philosopher[i].join();
    }

    return 0;
}

In this solution, we create an array of semaphores to represent the chopsticks, and initialize them with a count of 1 to indicate that they are available. We also create an array of threads to represent the philosophers, and define a function philosopher_behavior() to simulate each philosopher’s behavior.

In the philosopher_behavior() function, the philosopher alternates between thinking and eating. To eat, the philosopher must first acquire both the left and right chopsticks by calling the wait() method on the corresponding semaphores. Once the philosopher has both chopsticks, they can eat for a while, and then put down the chopsticks by calling the signal() method on the corresponding semaphores.

In the main() function, we initialize the semaphores and start the philosopher threads. Finally, we wait for the philosopher threads to finish by calling the join() method on each thread.