From 4abefd45fae7cb700ce5adc62e93d3d8f14a8f4c Mon Sep 17 00:00:00 2001 From: Tom Moguljak Date: Thu, 12 Oct 2023 14:01:22 +0200 Subject: [PATCH] Ajout de l'exo 3 TP 6 --- README.md | 31 +++++++++++++++++++-- TP6/Exo3/exo3.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+), 2 deletions(-) create mode 100644 TP6/Exo3/exo3.c diff --git a/README.md b/README.md index 0fc3e5b..41d5d17 100644 --- a/README.md +++ b/README.md @@ -460,7 +460,7 @@ $mytimeout nbsec com [arg ...] 1. Expliquez pourquoi ce code n'est pas correct (Faites varier `N`). -> Ce code n'est pas correct car il n'y a pas de synchronisation entre le père et le fils, donc le père peut envoyer le signal `SIGUSR1` au fils alors que le fils n'est pas encore en attente, ce qui fait que le fils ne va pas recevoir le signal et donc ne va pas afficher `Pong`. +> Ce code n'est pas correct car il n'y a pas de synchronisation entre le père et le fils, donc le père peut envoyer le signal `SIGUSR1` au fils alors que le fils n'est pas encore en attente, ce qui fait que parfois le fils ne va pas recevoir le signal et donc ne va pas afficher `Pong`. 2. Proposez une solution. @@ -593,4 +593,31 @@ int main(int argc, char *argv[]) │seq 2 N ├───►() ()───►│ F2 ├───►() ()───►│ F3 ├───►() ()───►│ F5 ├───►() ()───►│ P │ └────────┘ ────── └────────┘ ────── └────────┘ ────── └────────┘ ────── └────────┘ ``` -> Écrire un programme correspondant à ce schéma. \ No newline at end of file +> Écrire un programme correspondant à ce schéma. + +# TP 6 : Threads + +## Exercice 1 + +## Exercice 2 + +## Exercice 3 + +> On veut écrire un programme calculant la somme des entiers de `1` à `N` à l’aide de `M` threads. Chaque thread calculera la somme d’un sous-ensemble de ces entiers et la somme globale sera obtenue en calculant la somme des résultats intermédiaires de chaque thread. + +> Les entiers sont répartis uniformément entre les threads comme suit (exemple avec 3 threads) : + +- Thread 1 : 1, 4, 7, ... +- Thread 2 : 2, 5, 8, ... +- Thread 3 : 3, 6, 9, ... + +> Le programme doit lancer `M` threads, attendre qu’ils se terminent, faire la somme des résultats intermédiaires et afficher le résultat. Les valeurs `N` et `M` seront passées en ligne de commande. + +> Il est important que le programme respecte les points suivants : + +- L’implémentation ne doit utiliser aucune variable globale. +- Le travail à effectuer pour chaque thread créé doit être aussi équitable que possible, quelles que soient les valeurs `N` et `M` choisies par - l’utilisateur (ex : N=20, M=8). +- Évitez d’utiliser un tableau pour contenir les valeurs à additionner. +- Réaliser un test de validation automatiquement du résultat obtenu (vous devez connaître le résultat !). + +> Comparez le temps d'éxecution en fonction du nombre de threads. \ No newline at end of file diff --git a/TP6/Exo3/exo3.c b/TP6/Exo3/exo3.c new file mode 100644 index 0000000..1f038a0 --- /dev/null +++ b/TP6/Exo3/exo3.c @@ -0,0 +1,74 @@ +#include +#include +#include +#include +#include + +static inline double tstamp(void) +{ + struct timespec tv; + clock_gettime(CLOCK_REALTIME, &tv); + return tv.tv_sec + tv.tv_nsec * 1.0e-9; +} + +typedef struct thread_arg +{ + long int start; + long int limit; + long int inc; + long int S; +} thread_arg; + +void *slice(void *arg) +{ + thread_arg *a = (thread_arg *)arg; + long int S = 0; + + for (long int i = a->start; i <= a->limit; i = i + a->inc) + { + S += i; + } + a->S = S; + return NULL; +} + +int main(int argc, char *argv[]) +{ + long int N, M, S = 0; + double t1, t2; + thread_arg *args; + pthread_t *ths; + + assert(argc >= 3); + N = strtol(argv[1], NULL, 0); + M = strtol(argv[2], NULL, 0); + t1 = tstamp(); + + args = (thread_arg *)calloc(M, sizeof(thread_arg)); + assert(args != NULL); + + ths = (pthread_t *)calloc(M, sizeof(pthread_t)); + assert(ths != NULL); + + for (int i = 0; i < M; i++) + { + args[i].inc = M; + args[i].limit = N; + args[i].start = i + 1; + pthread_create(ths + i, NULL, slice, (void *)(args + i)); + } + + for (int i = 0; i < M; i++) + { + pthread_join(ths[i], NULL); + S += args[i].S; + } + + assert(S == N * (N + 1) / 2); + + t2 = tstamp(); + printf("S = %ld\n", S); + printf("t = %lf\n", t2 - t1); + + return 0; +} \ No newline at end of file