Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • main
1 result

Target

Select target project
  • remi.greub/g17_bykes_prog_concurrente
1 result
Select Git revision
  • main
1 result
Show changes
Commits on Source (2)
# 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
......@@ -11,25 +11,26 @@
#include <semaphore.h>
#define CITY_CAPACITY_MIN 2
#define DEPOT 0
#define USLEEP 0
#define CITY_CAPACITY_MIN 2 //min nb of bikes
#define DEPOT 0 //depot's index
#define USLEEP 1 //activate usleep() = 1 or no = 0
struct terminal{
int nb_bikesParked;
int nb_P_waiting;
sem_t *sem_FreeSlot;
sem_t *sem_BikeFree;
pthread_mutex_t *mutex;
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 -> one each terminal
sem_t *sem_BikeFree; //semaphore of the free bike -> one each terminal
pthread_mutex_t *mutex; //mutex -> one for each terminal
};
struct city{
int npersons;
int nSlots;
int nTerminal;
int personsFinished;
pthread_barrier_t b;
struct terminal *terminals;
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 it's iterations
pthread_barrier_t b; //barrier to wait for every person before ending the programm
struct terminal *terminals; //all the terminals in the city
};
void init_city(struct city* city, int nbTerminals, int npersons, int nbSlots);
......
......@@ -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;
......
......@@ -29,10 +29,8 @@ int main(int argc, char **argv){
struct person *persons = malloc(sizeof(struct person)*nbpersons);
struct Truck truck;
init_city(&city, nbterminals, nbpersons, nbslots);
printf("COUOCU COUCOU COUCOU %d\n",city.npersons);
init_civilians(persons, &city, nbTravels);
init_truck(&truck, &city);
printf("COUOCU COUCOU COUCOU \n");
if(pthread_create(threadTruck, NULL, trucks, (void*)&truck)!=0){
perror("thread creation error");
......