Ajout de l'exo 3 TP 6
This commit is contained in:
parent
062c53f218
commit
4abefd45fa
31
README.md
31
README.md
@ -460,7 +460,7 @@ $mytimeout nbsec com [arg ...]
|
|||||||
|
|
||||||
1. Expliquez pourquoi ce code n'est pas correct (Faites varier `N`).
|
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.
|
2. Proposez une solution.
|
||||||
|
|
||||||
@ -593,4 +593,31 @@ int main(int argc, char *argv[])
|
|||||||
│seq 2 N ├───►() ()───►│ F2 ├───►() ()───►│ F3 ├───►() ()───►│ F5 ├───►() ()───►│ P │
|
│seq 2 N ├───►() ()───►│ F2 ├───►() ()───►│ F3 ├───►() ()───►│ F5 ├───►() ()───►│ P │
|
||||||
└────────┘ ────── └────────┘ ────── └────────┘ ────── └────────┘ ────── └────────┘
|
└────────┘ ────── └────────┘ ────── └────────┘ ────── └────────┘ ────── └────────┘
|
||||||
```
|
```
|
||||||
> Écrire un programme correspondant à ce schéma.
|
> É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.
|
74
TP6/Exo3/exo3.c
Normal file
74
TP6/Exo3/exo3.c
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
#include <assert.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user