Os and networking Lab programs

Implementation of dining philosophers using threads

Problem Description
Develop a program to implement the solution of the dining philosopher’s
problem using threads. The input to the program is the number of philosophers to be seated around the table. Output shows the various stages that each philosopher passes through within a certain time. A philosopher can be in anyone of the three stages at a time: thinking, eating or finished eating.

Data Structures and Functions

The main data structures used here are: Arrays

The arrays represent the philosophers and corresponding chopsticks for them.Each element in the philosopher’s array corresponds to a thread and each element in the chopstick’s array corresponds to a mutex variable.

The functions used here are:

  1. pthread_mutex_init (&mutex, NULL) – initialization of mutex variable
  2. pthread_mutex_lock (&mutex) – attempt to lock a mutex
  3. pthread_mutex_unlock (&mutex) – unlock a mutex
  4. pthread_create (ptr to thread, NULL, (void*) func, (void*) )
  5. pthread_join (ptr to thread, &msg)-This function will make the main program wait until the called thread is finished executing it’s task.
  6. pthread_mutex_destroy (ptr to thread)-
  7. pthread_exit(NULL)

Note: while compiling this program use the following:
[root@Linux philo]# gcc –o dining dining.c -lpthread

Algorithm
Algorithm for process:
1. Start.
2. Declare and initialize the thread variables (philosophers) as required.
3. Declare and initialize the mutex variables (chopsticks) as required.
4. Create the threads representing philosophers.
5. Wait until the threads finish execution.
6. Stop.

Algorithm for thread (philosopher i) function:

  1. Start.
  2. Philosopher i is thinking.
  3. Lock the left fork spoon.
  4. Lock the right fork spoon.
  5. Philosopher i is eating.
  6. sleep
  7. Release the left fork spoon.
  8. Release the right fork spoon.
  9. Philosopher i Finished eating.
  10. Stop.

CODE USINGS THREADS ONLY

  1. #include<stdio.h>
    #include<stdlib.h>
    #include<pthread.h>
    #include<semaphore.h>
    void *func(int n);
    pthread_t philosopher[5];
    pthread_mutex_t chopstick[5];
    int main()
    {
    int i,k;
    void *msg;
    for(i=1;i<=5;i++)
    {
    k=pthread_mutex_init(&chopstick[i],NULL);
    if(k==-1)
    {
    printf(“\n Mutex initialization failed”);
    exit(1);
    }
    }
    for(i=1;i<=5;i++)
    {
    k=pthread_create(&philosopher[i],NULL,(void *)func,(int *)i);
    if(k!=0)
    {
    printf(“\n Thread creation error \n”);
    exit(1);
    }
    }
    for(i=1;i<=5;i++)
    {
    k=pthread_join(philosopher[i],&msg);
    if(k!=0)
    {
    printf(“\n Thread join failed \n”);
    exit(1);
    }
    }
    for(i=1;i<=5;i++)
    {
    k=pthread_mutex_destroy(&chopstick[i]);
    if(k!=0)
    {
    printf(“\n Mutex Destroyed \n”);
    exit(1);
    }
    }
    return 0;
    }void *func(int n)
    {
    printf(“\nPhilosopher %d is thinking “,n);
    pthread_mutex_lock(&chopstick[n]);//when philosopher 5 is eating he takes fork 1 and fork 5
    pthread_mutex_lock(&chopstick[(n+1)%5]);
    printf(“\nPhilosopher %d is eating “,n);
    sleep(3);
    pthread_mutex_unlock(&chopstick[n]);
    pthread_mutex_unlock(&chopstick[(n+1)%5]);
    printf(“\nPhilosopher %d Finished eating “,n);

    }

CODE USINGS SEMAPHORES ONLY

//Dining philosopher using multiprogramming using semaphores
#include<stdio.h>
#include<fcntl.h>
#include<semaphore.h>
#include<sys/wait.h>
#include<pthread.h>
#include<stdlib.h>
sem_t *sem[20];
int n;
int main()
{
pid_t cpid[5];
char semname[5];
int i,j=0;
n = 5;
for(i=0;i<n;i++)
{
sprintf(semname,”%d”,getpid()+i);
sem[i]=sem_open(semname,O_CREAT|O_EXCL,0666,1);
if(sem[i]==SEM_FAILED)
perror(“Unable to create semaphore”);

}

for(i=0;i<n;i++)
{

cpid[i]=fork();
if(cpid[i]==0)
break;

}
if(i==n)
{
int status;
for(i=0;i<n;i++)
waitpid(cpid[i],&status,WUNTRACED);

//waitpid is a function which waits for the child process to finish executing after that //control switches back to parent
for(i=0;i<n;i++)
{
sem_close(sem[i]);
sprintf(semname,”%d”,getpid()+i);
sem_unlink(semname);
}
}
else
reader(i);

}
int reader(int val)
{
printf(“%d Thinking\n”,val+1);
while(1)
{
sem_wait(sem[val%n]);
if(!sem_trywait(sem[(val+1)%n]))
break;
else
sem_post(sem[val%n]);
}
printf(“%d Eating\n”,val+1);
sleep(2);
sem_post(sem[val%n]);
sem_post(sem[(val+1)%n]);
printf(“%d Finished Eating\n”,val+1);
}

EXPECTED OUTPUT

REMEMBER :use the command -pthread

[root@localhost ~]$ gcc -o c dining.c -pthread
[root@localhost ~]$ ./c

Philosopher 1 is thinking
Philosopher 1 is eating
Philosopher 2 is thinking
Philosopher 3 is thinking
Philosopher 3 is eating
Philosopher 4 is thinking
Philosopher 5 is thinking
Philosopher 1 Finished eating
Philosopher 3 Finished eating
Philosopher 4 is eating
Philosopher 5 is eating
Philosopher 2 is eating
Philosopher 4 Finished eating
Philosopher 5 Finished eating
Philosopher 2 Finished eating

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a comment

Create a free website or blog at WordPress.com.