Skip to content
Snippets Groups Projects
Commit dd268dad authored by remi.greub's avatar remi.greub
Browse files

correction du dernier deadlock

parent 27b2f7d1
Branches
Tags
No related merge requests found
# G17 - TP Bykes
### Greub Remi
## Status du projet
Le projet dans son état est complet et fonctionnel avec quelques bugs a relever.
**Lancement du programme**
- via le makefile avec la cible `run` permettant de lancer le programme avec les arguments : S = 10, H = 100 , M = 10, N = 10 (modifiable avec la cible run ainsi)
```
make run ARGS="arg1 arg2 arg3 arg4"
```
- le lancement du programme se fait autrement via `./bykes arg1 arg2 arg3 arg4`
- arg1 -> nombre de sites (terminals)
- arg2 -> nombre de personnes a simuler (chacun dans un thread !)
- arg3 -> nombre de trajets par personnes
- arg4 -> nombre de bornes a vélos/bikes par sites/terminals
le programme est fonctionnel avec les arguments `10 100 10 10`, mais il peut se bloquer si l'on augmente le nombre de threads (notamment au dessus de 10000 threads avec par exemple les arguments ` ./bykes 100 10000 100 5000` ce qui devrait donné à la fin 499802 velos au total à la fin.)
## Fonctionnement de l'algorithme
l'algorithme est séparé en 3 librairies `civilian.h` (contenant l'algorithme des personnes), `Truck.h` (algo de la camionette) et enfin `city.h` qui est la structure principale avec les variables partagées dont les différents sites/terminals.
**city.h**
city contient les variables globales du programme :
```
#define USLEEP 1 //activate usleep() = 1 or no = 0
struct terminal{
int nb_bikesParked; //number of bikes parked in terminal
int nb_P_waiting; //number of persons waiting in terminal
sem_t *sem_FreeSlot; //semaphore of the free parking slots
sem_t *sem_BikeFree; //semaphore of the free bike
pthread_mutex_t *mutex; //mutex -> one for each terminal
};
struct city{
int npersons; //nb of persons in the city
int nSlots; //nb of slots for each terminal
int nTerminal; //nb of terminals in the city
int personsFinished; //nb of persons that finished
pthread_barrier_t b; //barrier to wait for every person
struct terminal *terminals; //all the terminals in the city
```
- d'abord le define USLEEP permettant d'activer les attentes usleep ou non
- la structure `city` qui contient toutes les variables partagée entre les threads, notamment personsFinished, et les terminals (les sites)
- chaque site contient un semaphore qui incrémente le BikeFree si qqun pose un vélo, puis décrémente le FreeSlots car une place de park sera prise.
- il contient également un mutex par terminal qui sera partagé aussi lorsque l'on accède aux variables partagées nb_bikesParked correspondant aux velos garés sur un terminal.
**civilian.h** + **Truck.h**
civilian.h contient une structure `person` qui contient l'essentiel de valeurs pour compter, mais aussi **afficher** les resultats sur le terminal.
```
struct person{
int num_thread;
int nb_travels;
int max_travels;
int i_terminals;
int nbTerminals;
int nslots;
};
```
Avec la structure city passée en variable globale dans la structure dans `civilian.c`.
Truck.h, das le principe fonctionne pareil, mais avec city passé directement en pointeur dans sa structure.
```
struct Truck{
int num_thread;
int n_bike;
int i_terminals;
int nbterminals;
int nslots;
int nbpersons;
struct city *city;
};
```
L'algorithme en lui même reprends le principe de producer consumer vu en cours :
- 2 types de sémaphores (1: velo de libre, 2: place de park de libre)
Les deux sont mis à jours ainsi :
1. qqun veut **prendre** un velo (est d'abord considéré en attente incrémenté dans des mutex), il va donc lancer un sem_wait en attente qu'un **velo** sois libre, pour ensuite le prendre et envoyer un sem_post indiquant qu'une **place** est libres
```
sem_wait(city_->terminals[pers->i_terminals].sem_BikeFree);
pthread_mutex_lock(city_->terminals[pers->i_terminals].mutex);
... //critical section
pthread_mutex_unlock(city_->terminals[pers->i_terminals].mutex);
sem_post(city_->terminals[pers->i_terminals].sem_FreeSlot);
```
2. la personne fait son voyage jusqu'à j (j!=i) et se mets à nouveau en attente pour cette fois **poser** son velo avec sem_wait -> **place** de libre. au quel cas, il fait comme plus haut mais en inverse.
```
sem_wait(city_->terminals[j].sem_FreeSlot);
pthread_mutex_lock(city_->terminals[j].mutex);
... //critical section
pthread_mutex_unlock(city_->terminals[j].mutex);
sem_post(city_->terminals[j].sem_BikeFree);
```
3. autrement, c'est le camion qui va de la même manière s'occuper de placer ou de prendre un velo comme indiqué sur le tp.
Ce qui conclu ce TP. merci !
\ No newline at end of file
...@@ -45,9 +45,6 @@ void *Persons(void *arg){ ...@@ -45,9 +45,6 @@ void *Persons(void *arg){
pthread_mutex_lock(city_->terminals[pers->i_terminals].mutex); pthread_mutex_lock(city_->terminals[pers->i_terminals].mutex);
city_->terminals[pers->i_terminals].nb_P_waiting -= 1; city_->terminals[pers->i_terminals].nb_P_waiting -= 1;
city_->terminals[pers->i_terminals].nb_bikesParked -= 1; //critical section city_->terminals[pers->i_terminals].nb_bikesParked -= 1; //critical section
//if(pers->i_terminals==4){
//printf("person %d leaves terminal %d by bike\n", pers->num_thread, pers->i_terminals);
//}
pthread_mutex_unlock(city_->terminals[pers->i_terminals].mutex); pthread_mutex_unlock(city_->terminals[pers->i_terminals].mutex);
sem_post(city_->terminals[pers->i_terminals].sem_FreeSlot); sem_post(city_->terminals[pers->i_terminals].sem_FreeSlot);
//if(pers->i_terminals==4){ //if(pers->i_terminals==4){
...@@ -101,9 +98,9 @@ void *Persons(void *arg){ ...@@ -101,9 +98,9 @@ void *Persons(void *arg){
pers->nb_travels += 1; pers->nb_travels += 1;
} }
printf("person %d stops\n", pers->num_thread); printf("person %d stops\n", pers->num_thread);
pthread_mutex_lock(city_->terminals[pers->i_terminals].mutex); //pthread_mutex_lock(city_->terminals[pers->i_terminals].mutex);
city_->personsFinished += 1; city_->personsFinished += 1;
pthread_mutex_unlock(city_->terminals[pers->i_terminals].mutex); //pthread_mutex_unlock(city_->terminals[pers->i_terminals].mutex);
pthread_barrier_wait(&city_->b); pthread_barrier_wait(&city_->b);
return NULL; return NULL;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment