# Thread: Problem with POSIX semaphores

1. ## Problem with POSIX semaphores

I have to do the following exercise (sorry for my English):

Jurassic Park is a museum with dino's and a park with a safari. There are M visitors and N cars for doing the safari, each of them can carry 2 visitors.

The visitors walk some time in the museum and later they wait for the cars. When a car is available, it carries his 2 visitors and run for an random time. If all the cars are being used, the visitors have to wait until one car is available. If the car is available but there is no visitor to carry, it will have to wait for visitors. If a car is available but there is only a visitor inside, the car will have to wait for another visitor. (so the car can just carry 2 visitors in each travel)

I have made the following program, but from 5 times i execute, 1 or 2 times it suffers interlocking or something that makes it not to finish.
Please, if you can help me....

Code:
```#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <unistd.h>

#define VISITANTES 6
#define COCHES   2
#define CICLOS   3

sem_t sem_visitante, sem_coche;

main (){
void *Coche (void *), *Visitante (void *);
int i, v[VISITANTES];
extern sem_t sem_coche, sem_visitante;

sem_init (&sem_coche, 0, 0);
sem_init (&sem_visitante, 0, 0);

srand (time (NULL));

for (i=0; i<VISITANTES; i++)
{
v[i] = i;
if (pthread_create (&visi[i], NULL, Visitante, &v[i]))
exit (1);
}

for (i = 0; i < COCHES; i++)
{
v[i] = i;
if (pthread_create (&coche[i], NULL, Coche, &v[i]))
exit (1);
}

for (i=0; i<VISITANTES; i++)

printf("\n\t**- Todos los visitantes han recorrido el safari -**\n");
}

void *Visitante (void *p)
{
extern sem_t sem_coche, sem_visitante;
int i, *index;

index = (int *)p;

for (i = 0; i < CICLOS; i++)
{
/* Visitante viendo/esperando en el museo. */
fprintf (stdout, "Visitante %d en el museo\n", *index+1);
sleep (rand()%4);

/* Espera para dar un paseo en coche. */
sem_post (&sem_coche);
sem_wait (&sem_visitante);

/* Paseo. */
fprintf (stdout, "Visitante %d subido en el coche\n", *index+1);
sleep (rand()%3);

/* Libera el coche. */
}
fprintf (stdout, "Visitante %d ha terminado sus %d ciclos.\n", *index+1, CICLOS);
}

void *Coche (void *p)
{
int *index, paseos = 0;
extern sem_t sem_coche, sem_visitante;
index = (int *) p;

/*Los coches siempre estan esperando viajeros*/
while(1)
{
/* Espera a ser necesitado. */
sem_wait (&sem_coche);

/* Espera a que haya dos viajeros. */
sem_wait (&sem_coche);

/*Realiza el safari*/
sleep (rand()%3);

/*Vuelve al museo y se bajan los 2 visitantes */
sem_post (&sem_visitante);
sem_post(&sem_visitante);
}
}```

2. Please post the output from a locked run.

3. Ah... wasn't hard to make it lock.

Basically... this is the current state of your program:
• Visitors 5, 1, 6, and 3 have completed their circuits.
• Visitor 2 gets into Car #1.
• Visitor 4 gets into Car #2.
• The cars never move because they will never fill up.

4. So the change to the algorithm needs to be that the passengers going to the cars, should always go to the car with just one person in it, if that exists.

Simple change.

5. Oh Thanks!!

But i don't know how to control the visitors for taking the appropiate car. With an if? or what and where?

6. Please, someone can help me?

7. Originally Posted by kaseo88
I have to do the following exercise (sorry for my English):

Jurassic Park is a museum with dino's and a park with a safari. There are M visitors and N cars for doing the safari, each of them can carry 2 visitors.

The visitors walk some time in the museum and later they wait for the cars. When a car is available, it carries his 2 visitors and run for an random time. If all the cars are being used, the visitors have to wait until one car is available. If the car is available but there is no visitor to carry, it will have to wait for visitors. If a car is available but there is only a visitor inside, the car will have to wait for another visitor. (so the car can just carry 2 visitors in each travel)

I have made the following program, but from 5 times i execute, 1 or 2 times it suffers interlocking or something that makes it not to finish.
Please, if you can help me....

Code:
```#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <unistd.h>

#define VISITANTES 6
#define COCHES   2
#define CICLOS   3

sem_t sem_visitante, sem_coche;

main (){
void *Coche (void *), *Visitante (void *);
int i, v[VISITANTES];
extern sem_t sem_coche, sem_visitante;

sem_init (&sem_coche, 0, 0);
sem_init (&sem_visitante, 0, 0);

srand (time (NULL));

for (i=0; i<VISITANTES; i++)
{
v[i] = i;
if (pthread_create (&visi[i], NULL, Visitante, &v[i]))
exit (1);
}

for (i = 0; i < COCHES; i++)
{
v[i] = i;
if (pthread_create (&coche[i], NULL, Coche, &v[i]))
exit (1);
}

for (i=0; i<VISITANTES; i++)

printf("\n\t**- Todos los visitantes han recorrido el safari -**\n");
}

void *Visitante (void *p)
{
extern sem_t sem_coche, sem_visitante;
int i, *index;

index = (int *)p;

for (i = 0; i < CICLOS; i++)
{
/* Visitante viendo/esperando en el museo. */
fprintf (stdout, "Visitante %d en el museo\n", *index+1);
sleep (rand()%4);

/* Espera para dar un paseo en coche. */
sem_post (&sem_coche);
sem_wait (&sem_visitante);

/* Paseo. */
fprintf (stdout, "Visitante %d subido en el coche\n", *index+1);
sleep (rand()%3);

/* Libera el coche. */
}
fprintf (stdout, "Visitante %d ha terminado sus %d ciclos.\n", *index+1, CICLOS);
}

void *Coche (void *p)
{
int *index, paseos = 0;
extern sem_t sem_coche, sem_visitante;
index = (int *) p;

/*Los coches siempre estan esperando viajeros*/
while(1)
{
/* Espera a ser necesitado. */
sem_wait (&sem_coche);

/* Espera a que haya dos viajeros. */
sem_wait (&sem_coche);

/*Realiza el safari*/
sleep (rand()%3);

/*Vuelve al museo y se bajan los 2 visitantes */
sem_post (&sem_visitante);
sem_post(&sem_visitante);
}
}```

I was thinking of some like this:

Before the visitor gets into any car for the tour

Look at each car and see if there is a car with 1 visitor in it, already.
If so, the new visitor looking for a car will get into this car, making it a fully loaded car, ready to leave on tour.
Code:
```/* to be placed right before the visitor enters any car for the tour */
/* look at each car */
for (i = 0; i < numeroDEcoches; i++)  {
if (coches[i] == 1) {                              /* the coche has solamente un visitante */
coche[i] = 2;                                      /* add un visitante a este coche */
/* add a line of code here to show that one less person is waiting for a car */
}
}```
Perdoneme mi espanol - es muy mal.

8. Change it to that only one car can be loading passengers at any given time.