dining philosophers problem solution using semaphores in c code example

Example 1: dining philosophers problem in c

/*
This code is contributed by :
Tanishq Vyas (github : https://github.com/tanishqvyas )

Use of Binary Semaphores has been made along with inversion of
last philosopher's order of picking chopsticks, in order to avoid
circular wait condition. Thus preventing deadlock.
*/

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>  //Header file for sleep(). man 3 sleep for details. 
#include <pthread.h> 
#define NUM_PHILOSOPHERS 5


// Binary Semaphores to keep track of Philosopher
int chopsticks[NUM_PHILOSOPHERS];

// Functions for philosophers
void *philosopher_behaviour(void* id)
{   
    int philosopher_number = *((int*)id);

    // Endless loop for philosopher
    while(1)
    {
        // Thinking Section
        printf("PID : (%ld)  Philosopher %d is THINKING\n", pthread_self(), philosopher_number+1);
        sleep(1);
        
        // Hungry Section
        printf("PID : (%ld)  Philosopher %d is Hungry\n", pthread_self(), philosopher_number+1);

        // Philosopher khaan Paan section
        while(1)
        {
            // Entry Section : Check for Chopsticks Availability
            // Check n pick left chopstick
            if(chopsticks[philosopher_number] == 1)
                continue;            
            // check n pick right Chopstick
            if(chopsticks[(philosopher_number+1)%NUM_PHILOSOPHERS] == 1)
                continue;

            chopsticks[philosopher_number] = 1;
            chopsticks[(philosopher_number+1)%NUM_PHILOSOPHERS] = 1;

            printf("PID : (%ld)  Philosopher %d picks #%d and #%d chopsticks up\n", pthread_self(), philosopher_number+1, philosopher_number+1, 1 + ((philosopher_number+1)%NUM_PHILOSOPHERS));

            // Khao Noodles Pel kr k
            printf("PID : (%ld)  Philosopher %d is Eating Noodles\n", pthread_self(), philosopher_number+1);
            sleep(1);

            // EXIT Section : Free the Chopsticks
            chopsticks[philosopher_number] = 0;
            chopsticks[(philosopher_number+1)%NUM_PHILOSOPHERS] = 0;
            
            printf("PID : (%ld)  Philosopher %d puts #%d and #%d chopsticks down\n", pthread_self(), philosopher_number+1, philosopher_number+1, 1 + ((philosopher_number+1)%NUM_PHILOSOPHERS));
            break;
        }
    }
}

void *philosopher_behaviour_rev(void* id)
{
    int philosopher_number = *((int*)id);

    // Endless loop for philosopher
    while(1)
    {
        // Thinking Section
        printf("PID : (%ld)  Philosopher %d is THINKING\n", pthread_self(), philosopher_number+1);
        sleep(1);
        
        // Hungry Section
        printf("PID : (%ld)  Philosopher %d is Hungry\n", pthread_self(), philosopher_number+1);

        // Philosopher khaan Paan section
        while(1)
        {
            // Entry Section : Check for Chopsticks Availability

            // check n pick right Chopstick
            if(chopsticks[(philosopher_number+1)%NUM_PHILOSOPHERS] == 1)
                continue;

            // Check n pick left chopstick
            if(chopsticks[philosopher_number] == 1)
                continue;            
            
            chopsticks[(philosopher_number+1)%NUM_PHILOSOPHERS] = 1;
            chopsticks[philosopher_number] = 1;

            printf("PID : (%ld)  Philosopher %d picks #%d and #%d chopsticks up\n", pthread_self(), philosopher_number+1, philosopher_number+1, 1 + ((philosopher_number+1)%NUM_PHILOSOPHERS));

            // Khao Noodles Pel kr k
            printf("PID : (%ld)  Philosopher %d is Eating Noodles\n", pthread_self(), philosopher_number+1);
            sleep(1);

            // EXIT Section : Free the Chopsticks
            chopsticks[philosopher_number] = 0;
            chopsticks[(philosopher_number+1)%NUM_PHILOSOPHERS] = 0;
            
            printf("PID : (%ld)  Philosopher %d puts #%d and #%d chopsticks down\n", pthread_self(), philosopher_number+1, philosopher_number+1, 1 + ((philosopher_number+1)%NUM_PHILOSOPHERS));

            break;
        }
    }
}

int main(int argc, char const *argv[])
{
    // Declare thread array
    pthread_t thread_ids[NUM_PHILOSOPHERS];
    int philosopher_numbers[NUM_PHILOSOPHERS];
    
    // Setting the Philosopher Numbers
    for (int i = 0; i < NUM_PHILOSOPHERS; i++)
    {
        philosopher_numbers[i] = i;
    }

    // Setting the state of all Chopsticks as 0
    for (int i = 0; i < NUM_PHILOSOPHERS; i++)
    {
        chopsticks[i] = 0;
    }

    // Thread Creation
    for (int i = 0; i < NUM_PHILOSOPHERS-1; i++)
    {
        pthread_create(&thread_ids[i], NULL, philosopher_behaviour, (void*)&philosopher_numbers[i]); 
    }

    // Reversing the last philosopher to avoid cyclic wait
    pthread_create(&thread_ids[NUM_PHILOSOPHERS-1], NULL, philosopher_behaviour_rev,(void*) &philosopher_numbers[NUM_PHILOSOPHERS-1]); 

    // Wait equivalent
    for (int i = 0; i < NUM_PHILOSOPHERS; i++)
    {
        pthread_join(thread_ids[i], NULL); 
    }

    exit(0);
}

Example 2: dining philosophers problem solution using semaphores in c

#include<stdio.h>#include<stdlib.h>#include<pthread.h>#include<semaphore.h>#include<unistd.h>sem_t room;sem_t chopstick[5];void * philosopher(void *);void eat(int);int main(){	int i,a[5];	pthread_t tid[5];		sem_init(&room,0,4);		for(i=0;i<5;i++)		sem_init(&chopstick[i],0,1);			for(i=0;i<5;i++){		a[i]=i;		pthread_create(&tid[i],NULL,philosopher,(void *)&a[i]);	}	for(i=0;i<5;i++)		pthread_join(tid[i],NULL);}void * philosopher(void * num){	int phil=*(int *)num;	sem_wait(&room);	printf("\nPhilosopher %d has entered room",phil);	sem_wait(&chopstick[phil]);	sem_wait(&chopstick[(phil+1)%5]);	eat(phil);	sleep(2);	printf("\nPhilosopher %d has finished eating",phil);	sem_post(&chopstick[(phil+1)%5]);	sem_post(&chopstick[phil]);	sem_post(&room);}void eat(int phil){	printf("\nPhilosopher %d is eating",phil);}/* BY - ANUSHKA DESHPANDE */

Tags:

Misc Example