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
No related tags found
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){
pthread_mutex_lock(city_->terminals[pers->i_terminals].mutex);
city_->terminals[pers->i_terminals].nb_P_waiting -= 1;
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);
sem_post(city_->terminals[pers->i_terminals].sem_FreeSlot);
//if(pers->i_terminals==4){
......@@ -101,9 +98,9 @@ void *Persons(void *arg){
pers->nb_travels += 1;
}
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;
pthread_mutex_unlock(city_->terminals[pers->i_terminals].mutex);
//pthread_mutex_unlock(city_->terminals[pers->i_terminals].mutex);
pthread_barrier_wait(&city_->b);
return NULL;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment