Programming Forums

Programming Forums (http://www.programmingforums.org/forumindex.php)
-   C (http://www.programmingforums.org/forum60.html)
-   -   Regarding Dining Philosophers Problem (http://www.programmingforums.org/showthread.php?t=15423)

joeserhal Mar 15th, 2008 10:24 PM

Regarding Dining Philosophers Problem
 
Hi there,
I'm trying to implement the Dining Philosophers problem, using a virtual distributed system, in which a host creates a number of virtual sites and communication means between them (message passing).
Hence, every site created should be thought of a "philosopher", and each will try to pick the forks (if available).
I have already implemented the whole Virtual Distributed System, and communications means, I am able to create the sites. But I need a way to allow the created "philosophers" to execute a the same time, trying to pick the forks...i.e, I don't want it to happen in sequential way (loop iteration, one after the other), it needs to be like some kind of a race, the one who gets there first can pick up the fork...Do you know what i mean??

Anybody has any ideas??
Thanks.

Ancient Dragon Mar 15th, 2008 11:25 PM

Re: Regarding Dining Philosophers Problem
 
>>Do you know what i mean??
I haven't the foggest idea of what you mean :)

Ooble Mar 16th, 2008 12:08 AM

Re: Regarding Dining Philosophers Problem
 
Simultaneous execution generally means multiple execution threads running in parallel. Look up threading for your particular OS (http://www.yolinux.com/TUTORIALS/Lin...ixThreads.html doesn't look bad for Linux) and get crackin'.

joeserhal Mar 23rd, 2008 9:23 PM

Re: Regarding Dining Philosophers Problem
 
I have finally written the code to solve the Dining philosopher problem using a virtual distributed system with message passing (as a mean of communication between each created site). However, when i run the program, it hangs.

The following is the code in which sites are created and the dining philosopher problem is handled using semaphores. I can successfully create sites ( I have tested it) so i know the problem comes from the Philo() function.

:

#include <stdio.h>
#include <time.h>
#include "vds.h"
#include "comm.h"
#include "queue.c"
#include <stdlib.h>
#include <unistd.h>

#define MEALS 10
#define EATING 0
#define THINKING 1
#define HUNGRY 2
#define THINK_TIME 4
#define EAT_TIME 4
#define N_PHIL 5

int chopstick[5] = {1,1,1,1,1};
int mutex = 1;
Queue block_mutex;
Queue block_chopstick[5];

void test();
void Philo();
void think(int ph_id);
void eat(int ph_id,int meal);
void put_forks(int ph_id);
void get_forks(int ph_id);
int Request(int chopstick,int philosopher);
void Release (int chopstick,int philosopher);
void sem_wait(int chopstick_num, char* type);
void sem_signal(int chopstick_num, char* type);


int main(argc, argv)
int argc;
char *argv[];
{
        int  sid;


        /*
        *
        * Site Initialization
        *
        *
        */
        setbuf( stdout, NULL ); /* no output buffering */

        if (argc != 4) {
                fprintf(stderr, "Usage: %s <SID> <NS HOST> <NS PORT>\n", argv[0]);
                exit(ERROR);
        }

        if (SiteSetup(atoi(argv[1]), argv[2], atoi(argv[3])) == ERROR) {
                fprintf(stderr, "SiteInit(%d) failed.\n", atoi(argv[1]));
                exit(ERROR);
        }

        printf("I am site %d. I am up and running\n", atoi(argv[1]));


        Philo();        /* This is a simple test routine. You should comment it out */

        /*
        *
        * Lab 2 Protocol
        *
        * Philo_Init()
        * while ( 1 ) {       
        *  Philosophers simulation code
        *
          * }
        *
        */



        /*
        *
        * Site Termination
        *
        *
        */
        SiteExit();
}


void Philo()
{
    char *MSG = (char *)malloc(MAX_MSG_LEN);
    int i, sender;
    char delims[] = " "; 
    char *result = NULL; 
     
    block_mutex = CreateQueue(5);
   
    for(i=0;i<5;i++)
        block_chopstick[i] = CreateQueue(2);
   
    srand(MySID);
    if(MySID>=1 && MySID<=5)
    {
      while(1)
      {
              for (i=0;i<MEALS;i++)
              {
                think(MySID);
                get_forks(MySID);
                eat(MySID,i);
                put_forks(MySID);
              }
              printf("Philosopher %d's thread has exited\n",MySID);
        }   
    }
    else
    if(MySID == 6)  //if I am the site responsable for synchronization
    {
      //Do the work for the semaphores, increments and decrements
      Receive(MSG, &sender);
      result = strtok( MSG, delims );
      if(strcmp(result,"Wait")==0)  //check if the message received corresponds to a sem_wait
      {
        result = strtok( NULL, delims );
        if(strcmp(result,"chopstick")==0) //check if the semaphore needed to be handled is "chopstick"
        {
            result = strtok( NULL, delims );
            for(i=0;i<5;i++)
            {
                if(i == atoi(result))
                {
                  chopstick[i]--;
                  if(chopstick[i]<0)
                    Enqueue(sender,block_chopstick[i]);//BLOCK the philosopher, put on waiting queue of this chopstick
                  else
                      Send("OK", sender);
                  }
            }
        }
        else
        if(strcmp(result,"mutex")==0) //check if the semaphore needed to be handled is "mutex"
        {
                  mutex--;
                  if(mutex<0)
                    Enqueue(sender,block_mutex);//BLOCK the philosopher, put on waiting queue -> mutex[sender]=0
                  else
                      Send("OK", sender);
        }
      } //end of sew-wait handling
      else 
      if(strcmp(result,"Signal")==0)  //check if the message received corresponds to a sem_signal
      {
        result = strtok( NULL, delims );
        if(strcmp(result,"chopstick")==0) //check if the semaphore needed to be handled is "chopstick"
        {
            result = strtok( NULL, delims );
            for(i=0;i<5;i++)
            {
                if(i == atoi(result))
                {
                  chopstick[i]++;
                  if(chopstick[i]<=0)
                    Dequeue(block_chopstick[i]);//NBLOCK philosopher waiting on this chopstick from the blocking queue of this chopstick
                  Send("OK", sender);
                  }
            }
        }
        else
        if(strcmp(result,"mutex")==0) //check if the semaphore needed to be handled is "mutex"
        {
                  mutex++;
                  if(mutex<=0)
                    Dequeue(block_mutex);//NBLOCK philosopher waiting on mutex from the blocking queue of mutex
                  Send("OK", sender);
        }
      }  //end of sem_signal handling         
   
   
    }//end of job for site responsable for synchronization
   
}
 
 
 
int Request(int chopstick,int philosopher)
{
        return 1;
}

void Release (int chopstick,int philosopher)
{
}
 
void sem_wait(int chopstick_num, char* type)
{
    char *MSG = (char *)malloc(MAX_MSG_LEN);
    char* string;
    int i,sender=6;
    if (strcmp(type,"chopstick")==0) //if dealing with semaphore "chopstick"
    {
          for(i=0;i<N_PHIL;i++)
          {
            if(i==chopstick_num)
            {
                sprintf(string, "Wait %s %d", type, i);
                Send(string, 6);
            }
          }
    }
    else
    if(strcmp(type,"mutex")==0)  //if dealing with semaphore mutex
    {
                sprintf(string, "Wait mutex"); 
                Send(string, 6);
    } 
    Receive(MSG, &sender);
}


void sem_signal(int chopstick_num, char* type)
{
    char *MSG = (char *)malloc(MAX_MSG_LEN);
    char* string;
    int i,sender=6;
    if (strcmp(type,"chopstick")==0) //if dealing with semaphore "chopstick"
    {
          for(i=0;i<N_PHIL;i++)
          {
            if(i==chopstick_num)
            {
                sprintf(string, "Signal %s %d", type, i);
                Send(string, 6);
            }
          }
    }
    else
    if(strcmp(type,"mutex")==0)  //if dealing with semaphore mutex
    {
                sprintf(string, "Signal mutex"); 
                Send(string, 6);
    } 
    Receive(MSG, &sender);
}


     
void think(int ph_id)
{
  int wait_time;
  wait_time=rand()%THINK_TIME+1;
  printf("\tPhilosopher %d is thinking for %d seconds.\n",ph_id,wait_time);
  sleep(wait_time);
}


void get_forks(int ph_id)
{
  int left=0,right=0;
  while(!left){
          sem_wait(-1,"mutex");
        left=Request(ph_id-1,ph_id);
        sem_signal(-1,"mutex");
        if (!left)
          sleep(1);
  }
  sem_wait(ph_id-1,"chopstick");
  while(!right){
        sem_wait(-1,"mutex");
        right=Request((ph_id)%N_PHIL,ph_id);
        sem_signal(-1,"mutex");
        if (!right)
        {
          sleep(1);
        }
  }
  sem_wait((ph_id)%N_PHIL,"chopstick");
}


void eat(int ph_id,int meal)
{
  int wait_time;
  wait_time=rand()%EAT_TIME+1;
  printf("\tPhilosopher %d is eating meal %d for %d seconds.\n",ph_id,meal+1,wait_time);
  sleep(wait_time);
}


void put_forks(int ph_id)
{
  int i;
  sem_wait(-1,"mutex");
  Release(ph_id-1,ph_id);
  Release((ph_id)%N_PHIL,ph_id);
  sem_signal(ph_id-1,"chopstick");
  sem_signal((ph_id)%N_PHIL,"chopstick");
  sem_signal(-1,"mutex");
}



void test()
{
        /*
        * To test: read, understand, then issue the command:
          * vds <filename>, where <filename> is in local dir and
        * contains:
        *
        * ------ start file
        * 3
        * 1 sand
        * 2 sand
        * 3 sand
        * <your vds bin path>
        * ------ end file
        *
        */

    char *MSG = (char *)malloc(MAX_MSG_LEN);
        int sender;

        sleep(3);
        if (MySID==3)  {
                sleep(3);
                Send("Hi, I am 3 sending you my greetings\n\0", 2);
        }
        else if (MySID==2) {
                Send("Hi, I am 2 sending you my greetings\n\0", 3);
        }

        if(MySID==3 || MySID==2) {
                Receive(MSG, &sender);
                printf("Site %d: Received this msg fm site %d: %s\n", MySID, sender, MSG);
        }
       
}




The output it produces is:
http://img186.imageshack.us/my.php?image=outputxm7.jpg

it doesnt seem to execute the getforks(),eat(), putforks() functions....

Anybody can help me out with it?

Ancient Dragon Mar 23rd, 2008 10:53 PM

Re: Regarding Dining Philosophers Problem
 
:

int main(argc, argv)
int argc;
char *argv[];
{

OMG you mean some people still code like that??? I haven't seen that style of coding for probably 20 or more years. Is your compiler really that ancient? Even the C standards don't recommend that original K&R style. I see you didn't use that style anywhere else so why in main() ?
:

int main(int argc, char* argv[])
{


I know my comments don't help solve your problem, but it will take some time to sift through your code.

joeserhal Mar 23rd, 2008 11:10 PM

Re: Regarding Dining Philosophers Problem
 
hehe...actually, some part of the main program was given to me, and i wrote the Philo function, and all other functions related to it.

Now, I can get some of the philosophers to eat, but then it deadlocks. I want to solve the deadlock, but not sure how. I wanna try to force preemption of ressources: i.e, if one philosopher holds 1 chopstick, but can't get the other one, then he has to release the one he already holds...
I guess this has to be done in the get_forks function:
:

void get_forks(int ph_id)
{
  int left=0,right=0;
  while(!left)
  {
          sem_wait(-1,"mutex");
        left=Request(ph_id-1,ph_id);
        sem_signal(-1,"mutex");
        if (!left)
          sleep(1);
  }
  sem_wait(ph_id-1,"chopstick");
  while(!right)
  {
    sem_wait(-1,"mutex");
        right=Request((ph_id)%N_PHIL,ph_id);
        sem_signal(-1,"mutex");
        if (!right)
        {
          sleep(1);
        }
  }
  sem_wait((ph_id)%N_PHIL,"chopstick");
}


Any ideas??

rhish.franks Mar 24th, 2008 3:50 PM

Re: Regarding Dining Philosophers Problem
 
yes i got what you mean. Just can you elaborate what you want. Do you need another code that i have! Free!

rhish.franks Mar 24th, 2008 3:50 PM

Re: Regarding Dining Philosophers Problem
 
yours code is tooo much big, can be made smaller!

joeserhal Mar 24th, 2008 5:57 PM

Re: Regarding Dining Philosophers Problem
 
umm, yeah i guess my code is too big, but I don't know how to make it smaller...Also, i tried to edit it to preempt philosophers to release the left chopstick, whenever a request for a right chopstick could not be granted,...but i ave another problem, i can't seem to keep track on the number of eating phases...i mean everytime a philosopher eats, a counter should be incremented, and a there should be a total of 10 eating phases. Bu i cant't seem to correctly update the global variable (I am using a global variable count=0)
and then:
:

while(count<10)
              {
                think(MySID);
                get_forks(MySID);
                eat(MySID,i);
                put_forks(MySID);
              }


Then everytime a philosopher eats, it increments the global variable by 1...but i keep getting an output similar to this:
Philosopher 2 is eating meal 1 for 3 seconds.
...
Philosopher 1 is eating meal 1 for 2 seconds.
Philosopher 4 is eating meal 1 for 4 seconds.
....
Philosopher 2 is eating meal 2 for 5 seconds.
Philosopher 4 is eating meal 2 for 3 seconds.
....

Any ideas?


All times are GMT -5. The time now is 4:23 AM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC