Importation du code depuis GitHub

This commit is contained in:
gasc 2021-08-22 13:28:10 +02:00
commit 05476b94ad
13 changed files with 1080 additions and 0 deletions

10
README.md Normal file
View file

@ -0,0 +1,10 @@
# Cours de programmation système & multi-threading (I4IRTR11)
Partage de mes TD et TP de programmation système & multi-threading effectués lors de mon S6 à l'INSA de Toulouse.
## Liste des TD validés à présent :
* TD1
* TD2
* TD3
* TD4
* TD5
* TD6 - mais on peut mieux faire

33
TD/TD1/main.c Normal file
View file

@ -0,0 +1,33 @@
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
void * fn_thread (void * p_int) {
for (int i = 0; i < *(int *) p_int; ++i) {
printf("et mon courroux\n");
sleep(1);
}
pthread_exit(0);
}
int main () {
int M = 0;
int N = 0;
pthread_t p1;
printf("Saisir M puis N : \n");
scanf ("%d", &M);
scanf ("%d", &N);
printf("Ok ! \n");
pthread_create (& p1, NULL, fn_thread, (void *) &N);
for (int i = 0; i < M; ++i) {
printf("Coucou\n");
sleep(1);
}
pthread_join(p1, NULL);
return 0;
}

41
TD/TD2/main.c Normal file
View file

@ -0,0 +1,41 @@
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
double * px = NULL;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void * fn_thread (void * p_int) {
for (int i = 0; i < *(int *) p_int; ++i) {
pthread_mutex_lock(& mutex);
printf("%f\n", *px);
pthread_mutex_unlock(& mutex);
}
pthread_exit(0);
}
int main () {
int max = 0;
pthread_t p1;
printf("Saisir max : \n");
scanf ("%d", &max);
printf("Ok ! \n");
double x = 1.0;
px = &x;
pthread_create (& p1, NULL, fn_thread, (void *) &max);
for (int i = 0; i < max; ++i) {
pthread_mutex_lock(& mutex);
px = NULL;
printf("i : %d\n", i);
px = &x;
pthread_mutex_unlock(& mutex);
}
pthread_join(p1, NULL);
return 0;
}

68
TD/TD3/main.c Normal file
View file

@ -0,0 +1,68 @@
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
// Ressources disponible
int M = 4;
// Mutex
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
void prendre_ressource(int rsc){
if (pthread_mutex_lock(&mutex))
exit(-1);
while (rsc > M)
pthread_cond_wait(&cond, &mutex);
if (M - rsc >= 0)
M -= rsc;
else
exit(1);
pthread_mutex_unlock(&mutex);
}
void liberer_ressource(int rsc){
if (pthread_mutex_lock(&mutex))
exit(-1);
M += rsc;
pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&mutex);
}
void * fn_thread (void * p_int) {
int rsc = *(int *) p_int;
printf("Thread en attente pour %d ressource(s)...\n", rsc);
prendre_ressource(rsc);
printf("Thread a pris %d ressource(s)...\n", rsc);
sleep(rsc);
printf("%d ressource(s) utilisée(s) et rendue(s)...\n", rsc);
liberer_ressource(rsc);
printf("Thread (à %d rsc) fini...\n", rsc);
pthread_exit(0);
}
int main () {
pthread_t p1;
pthread_t p2;
pthread_t p3;
int rsc1 = 3;
int rsc2 = 2;
int rsc3 = 1;
pthread_create (& p1, NULL, fn_thread, (void *) &rsc1);
pthread_create (& p2, NULL, fn_thread, (void *) &rsc2);
pthread_create (& p3, NULL, fn_thread, (void *) &rsc3);
pthread_join(p1, NULL);
pthread_join(p2, NULL);
pthread_join(p3, NULL);
return 0;
}

50
TD/TD4/main.c Normal file
View file

@ -0,0 +1,50 @@
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
// Ressources disponible
int N = 3;
// Once
pthread_once_t once = PTHREAD_ONCE_INIT;
pthread_key_t key;
int incrementation() {
int *s_int;
s_int = (int*)pthread_getspecific(key);
return ++(*s_int);
}
void fonction_init() {
printf("Initialisation...\n");
pthread_key_create(&key, NULL);
}
void * fn_thread (void * n) {
pthread_once(&once, fonction_init);
int* s_int;
s_int = malloc(sizeof(int));
*s_int = pthread_self();
pthread_setspecific(key, (void *)s_int);
for (int i = 0; i < N; ++i){
printf("Boucle : %d\n", incrementation());
}
pthread_exit(0);
}
int main () {
pthread_t p1;
pthread_t p2;
pthread_create (& p1, NULL, fn_thread, NULL);
pthread_create (& p2, NULL, fn_thread, NULL);
fn_thread(NULL);
pthread_join(p1, NULL);
pthread_join(p2, NULL);
return 0;
}

47
TD/TD5/main.c Normal file
View file

@ -0,0 +1,47 @@
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#define max 6
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void unlock(){
pthread_mutex_unlock(& mutex);
}
void * fn_thread (void * n) {
pthread_mutex_lock(& mutex);
printf("[THREAD] J'ai le mutex.\n");
for (int i = 0; i < max; ++i){
printf("[THREAD] tid: %ld\n", pthread_self());
sleep(1);
}
pthread_mutex_unlock(& mutex);
pthread_exit(0);
}
int main () {
pthread_t p1;
for (int i = 0; i < 2; ++i){
pthread_create (& p1, NULL, fn_thread, NULL);
pthread_cleanup_push( &unlock, NULL );
for (int i = 0; i < max/2; ++i){
printf("[MAIN] pid: %d\n", getpid());
sleep(1);
}
pthread_cancel(p1);
pthread_cleanup_pop(1);
sleep(1);
}
return 0;
}

66
TD/TD5/sig.c Normal file
View file

@ -0,0 +1,66 @@
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <signal.h>
#define max 6
void handler_sigusr1(int sig) {
printf("PID %d a reçu un SIGUSR1 : %d\n", getpid(), sig);
}
void handler_sigusr2(int sig) {
printf("PID %d a reçu un SIGUSR2 : %d\n", getpid(), sig);
exit(2);
}
void * fn_thread (void * n) {
// Masque tous les signaux sauf SIGUSR1
sigset_t ens_signal;
sigfillset(&ens_signal);
sigdelset(&ens_signal,SIGUSR1);
sigprocmask(SIG_SETMASK, &ens_signal,NULL);
while (1){
printf("THREAD up and running.\n");
sleep(1);
}
pthread_exit(0);
}
int main () {
printf("Entry.\n");
// Configuration des signaux
struct sigaction action;
struct sigaction action2;
action.sa_handler = handler_sigusr1;
action2.sa_handler = handler_sigusr2;
if (sigaction(SIGUSR1, &action, NULL) || sigaction(SIGUSR2, &action2, NULL)) {
printf("Erreur handler (SIGUSR1).\n");
exit(-1);
}
// Création du thread
pthread_t p1;
pthread_create (& p1, NULL, fn_thread, NULL);
// Masque tous les signaux sauf SIGUSR2
sigset_t ens_signal;
sigfillset(&ens_signal);
sigdelset(&ens_signal,SIGUSR2);
sigprocmask(SIG_SETMASK, &ens_signal,NULL);
while (1){
printf("MAIN up and running (pid: %d).\n", getpid());
sleep(1);
}
return 0;
}

77
TD/TD6/main.c Normal file
View file

@ -0,0 +1,77 @@
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/time.h>
#define NB_THREAD 4
#define F 10000000
// Nombre de point à l'intérieur du cercle
int retvals[NB_THREAD];
int t_num = 0;
/// Fonction de calcul en thread
void * fn_thread (void * p_int) {
// Le thread récupère un numéro
int num = t_num;
++t_num;
long double x, y;
int fn = F/NB_THREAD;
int in = 0;
for (int i = 0; i < fn; ++i) {
// On tire aléatoirement x et y entre -1 et 1
x = (long double)rand()/(long double)(RAND_MAX);
y = (long double)rand()/(long double)(RAND_MAX);
if ((x*x) + (y*y) <= 1.0)
++in;
}
retvals[num] = in;
pthread_exit(0);
}
int main () {
pthread_t threads[NB_THREAD];
// Graine aléatoire avec le temps
srand(time(NULL));
// Outils pour le chronometre
struct timeval begin, end;
gettimeofday(&begin, NULL);
// Lancement des threads
for (int j = 0; j < NB_THREAD; ++j) {
if (pthread_create(&threads[j], NULL, fn_thread, NULL) != 0) {
fprintf(stderr, "Cannot create thread # %d\n", j);
return 1;
}
}
// Joining threads
for (int i = 0; i < NB_THREAD; ++i) {
pthread_join(threads[i], NULL);
}
//Summing all "in" points
int in = 0;
for (int i = 0; i < NB_THREAD; ++i) {
in += retvals[i];
}
// Calculing pi
long double pi = ((long double) in * 4.0) / (long double) F;
// Stopping timer
gettimeofday(&end, NULL);
//printf("Ratio inside / outside : %d/%d\n", in, F - in);
printf("Valeur calculée de pi : %Lf\n", pi);
printf("Nombre de thread : %d\n", NB_THREAD);
printf("Nombre de point : %d\n", F);
printf("Time: %ld microseconds\n", ((end.tv_sec - begin.tv_sec)*1000000L + end.tv_usec) - begin.tv_usec);
return 0;
}

98
TP/TP1/main.c Normal file
View file

@ -0,0 +1,98 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#define NB_ITR 100000
void handler_sigusr1(int sig) {
printf("PID %d a reçu un SIGUSR1 : %d\n", getpid(), sig);
exit(2);
}
void handler_sigchld(int sig) {
printf("PID %d a reçu un SIGCHLD : %d\n", getpid(), sig);
printf("Le fils est mort...\n");
}
int main() {
// Variables fork
int pid = 0;
// Variables gestion des signaux
struct sigaction action;
struct sigaction action2;
action.sa_handler = handler_sigusr1;
action2.sa_handler = handler_sigchld;
// Variables tubes
int p1[2];
int p2[2];
int tsfr = 0;
int tsfr2 = 0;
// Outils pour le chronometre
struct timeval begin, end;
// Initialisation des signaux
if (sigaction(SIGUSR1, &action, NULL)) {
printf("Erreur handler (SIGUSR1).\n");
exit(-1);
}
if (sigaction(SIGCHLD, &action2, NULL)) {
printf("Erreur handler (SIGCHLD).\n");
exit(-1);
}
// Initialisation des tubes
if (pipe(p1) || pipe(p2)) {
printf("Erreur pipe.\n");
exit(-1);
}
// Fork
switch (pid = fork()) {
case -1:
printf("Erreur fork.\n");
exit(-1);
break;
case 0:
printf("Le fils a correctement démarré (PID %d)\n", getpid());
// On lit, on incrémente et on renvoie
while (1) {
read(p1[0], &tsfr2, sizeof(tsfr2));
++tsfr2;
write(p2[1], &tsfr2, sizeof(tsfr2));
}
break;
default:
printf("Le père est ok (PID %d), le PID du fils est %d\n", getpid(), pid);
// Comme le fils, mais on chronometre
int nb_boucle = 0;
gettimeofday(&begin, NULL);
while (nb_boucle < NB_ITR) {
++tsfr;
write(p1[1], &tsfr, sizeof(tsfr));
read(p2[0], &tsfr, sizeof(tsfr));
nb_boucle++;
}
gettimeofday(&end, NULL);
kill(pid, SIGUSR1);
// On calcul le débit
int delta = ((end.tv_sec - begin.tv_sec)*1000000L + end.tv_usec) - begin.tv_usec;
int debit = (nb_boucle*2*sizeof(tsfr2)*8)/(delta); // (delta est déjà en us)
printf("Débit calculé : %d Mb/s\n", debit);
printf("[DEBUG] delta : %d us, tsfr : %d\n", delta, tsfr);
return debit;
break;
}
}

110
TP/TP1/tube_nomme.c Normal file
View file

@ -0,0 +1,110 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#define NB_ITR 1000
void utilisation() {
printf("Usage : ./a.out [c] [s]\n");
exit(-1);
}
void server() {
printf("Server mode (ping only)...\n");
// Variables tube nommé
int d_lect_1, d_ecr_1;
int d_lect_2, d_ecr_2;
printf("Création des tubes...");
if (mkfifo("/tmp/tube1", S_IRUSR | S_IWUSR | S_IRGRP)
|| mkfifo("/tmp/tube2", S_IRUSR | S_IWUSR | S_IRGRP)) {
printf("Erreur tube.\n");
exit(-1);
}
printf("OK\n");
printf("Ouverture des tubes...");
if (!(d_lect_1 = open("/tmp/tube1", O_RDONLY))){
printf("Erreur ouverture tube (READ).\n");
exit(-1);
}
printf("OK1...");
if (!(d_ecr_2 = open("/tmp/tube2", O_WRONLY))){
printf("Erreur ouverture tube (WRITE).\n");
exit(-1);
}
printf("OK2\n");
// On lit, on incrémente et on renvoie
int tsfr = 0;
while (1) {
read(d_lect_1, &tsfr, sizeof(tsfr));
++tsfr;
write(d_ecr_2, &tsfr, sizeof(tsfr));
}
}
void client() {
printf("Client mode...\n");
// Variables tube nommé
int d_lect_1, d_ecr_1;
int d_lect_2, d_ecr_2;
printf("Ouverture des tubes...\n");
if (!(d_ecr_1 = open("/tmp/tube1", O_WRONLY))){
printf("Erreur ouverture tube (WRITE).\n");
exit(-1);
}
if (!(d_lect_2 = open("/tmp/tube2", O_RDONLY))){
printf("Erreur ouverture tube (READ).\n");
exit(-1);
}
printf("Tubes ouverts.\n");
// Outils pour le chronometre
struct timeval begin, end;
// Ping pong
int tsfr = 0;
int nb_boucle = 0;
printf("Lancement du chronometre.\n");
gettimeofday(&begin, NULL);
while (nb_boucle < NB_ITR) {
++tsfr;
write(d_ecr_1, &tsfr, sizeof(tsfr));
read(d_lect_2, &tsfr, sizeof(tsfr));
nb_boucle++;
}
gettimeofday(&end, NULL);
// On calcul le débit
int delta =
((end.tv_sec - begin.tv_sec) * 1000000L + end.tv_usec) - begin.tv_usec;
int debit =
(nb_boucle * 2 * sizeof(tsfr) * 8) / (delta); // (delta est déjà en us)
printf("Débit calculé : %d Mb/s\n", debit);
printf("[DEBUG] delta : %d us, tsfr : %d\n", delta, tsfr);
}
int main(int argc, char **argv) {
// Arguments parsing
if (argc != 2) {
utilisation();
}
if (*argv[1] == 's') {
server();
} else if (*argv[1] == 'c') {
client();
} else {
utilisation();
}
}

111
TP/TP2/main.c Normal file
View file

@ -0,0 +1,111 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#define KEY 30
/*
* TP 2 partie sémaphore OK.
* L'exclusion mutuelle est observée correctement.
* Lancez d'abord le serveur puis le client.
* Si echec, essayez de changer la clé.
*/
void utilisation() {
printf("Usage : ./a.out [c] [s]\n");
exit(-1);
}
void server() {
int key = KEY;
int init = 1;
char recv[1];
struct sembuf op;
int sem = semget((key_t)key, 1, 666 | IPC_CREAT);
if (sem < 0) {
printf("Erreur création sémaphore.\n");
exit(-1);
}
if (semctl(sem, 0, SETVAL, init) == -1) {
printf("Erreur initialisation sémaphore.\n");
exit(-1);
}
op.sem_num = 0;
op.sem_flg = 0;
while (1) {
op.sem_op = -1;
printf("Serveur en attente...\n");
if (semop(sem, &op, 1)) {
printf("Erreur attente.\n");
exit(-1);
}
printf("Le serveur a la main. Entrez qqc : ");
fgets(recv, 10, stdin);
op.sem_op = 1;
printf("Le serveur rend la main.\n");
if (semop(sem, &op, 1)) {
printf("Erreur op.\n");
exit(-1);
}
}
}
void client() {
int key = KEY;
int init = 0;
char recv[1];
struct sembuf op;
int sem = semget((key_t)key, 0, 0);
if (sem < 0) {
printf("Erreur création sémaphore.\n");
exit(-1);
}
op.sem_num = 0;
op.sem_flg = 0;
while (1) {
op.sem_op = -1;
printf("Client en attente...\n");
if (semop(sem, &op, 1)) {
printf("Erreur attente.\n");
exit(-1);
}
printf("Le client a la main. Entrez qqc : ");
fgets(recv, 10, stdin);
op.sem_op = 1;
printf("Le client rend la main.\n");
if (semop(sem, &op, 1)) {
printf("Erreur op.\n");
exit(-1);
}
}
}
int main(int argc, char **argv) {
// Arguments parsing
if (argc != 2) {
utilisation();
}
if (*argv[1] == 's') {
server();
} else if (*argv[1] == 'c') {
client();
} else {
utilisation();
}
}

195
TP/TP2/shared_mem.c Normal file
View file

@ -0,0 +1,195 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#define KEY 160
#define NB_ITERATION 100000
/*
* TP2 Partie 3 Communication par mémoire partagée
* On observe une alternance correct et derterministe.
* Le débit calculé est cohérent
*/
void utilisation() {
printf("Usage : ./a.out [c] [s]\n");
exit(-1);
}
int main(int argc, char *argv[]) {
int server = -1;
struct timeval begin, end;
// Variables SHM
int key_shm = KEY;
int *shm = NULL;
int shmid = 0;
// Variables IPC
int key = KEY;
int init_s = 0;
int init_c = 1;
char recv[1];
struct sembuf op;
int sem_s, sem_c;
/* Traitement des arguments */
if (argc != 2) {
utilisation();
}
if (*argv[1] == 's') {
server = 1;
sem_s = semget((key_t)key, 1, 666 | IPC_CREAT);
sem_c = semget((key_t)key+1, 1, 666 | IPC_CREAT);
} else if (*argv[1] == 'c') {
sem_s = semget((key_t)key, 0, 0);
sem_c = semget((key_t)key+1, 0, 0);
server = 0;
} else {
utilisation();
}
/* Création du sémaphore */
if (sem_s < 0 || sem_c < 0) {
printf("Erreur création sémaphore.\n");
exit(-1);
}
/* Initialisation du sémaphore */
if (server) {
if (semctl(sem_s, 0, SETVAL, init_s) == -1 || semctl(sem_c, 0, SETVAL, init_c) == -1) {
printf("Erreur initialisation sémaphore.\n");
exit(-1);
}
}
op.sem_num = 0;
op.sem_flg = 0;
/* Création de la SHM */
if (!(shmid = shmget((key_t)key_shm, 4, 0666 | IPC_CREAT))) {
printf("Erreur création SHM.\n");
exit(-1);
}
/* Attachement de la shm */
if (!(shm = (int *)shmat(shmid, 0, 0))) {
printf("Erreur attache SHM.\n");
exit(-1);
}
////////SERVER////////
if (server) {
printf("Mode serveur.\n");
for (int i = 0; i < (NB_ITERATION/2); ++i) {
op.sem_op = -1;
//printf("Serveur en attente...\n");
if (semop(sem_s, &op, 1)) {
printf("Erreur attente.\n");
exit(-1);
}
//printf("On incrémente le shm...");
(*shm)++;
//printf("Fait.\n");
//sleep(1);
op.sem_op = 1;
//printf("Le serveur rend la main.\n");
if (semop(sem_c, &op, 1)) {
printf("Erreur op.\n");
exit(-1);
}
}
}
////////CLIENT////////
else {
printf("Mode client.\n");
printf("Lancement du chronometre.\n");
gettimeofday(&begin, NULL);
for (int i = 0; i < (NB_ITERATION/2); ++i) {
op.sem_op = -1;
//printf("Client en attente...\n");
if (semop(sem_c, &op, 1)) {
printf("Erreur attente.\n");
exit(-1);
}
//printf("On incrémente le shm...");
(*shm)++;
//printf("Fait.\n");
//sleep(1);
//printf("Le client rend la main.\n");
op.sem_op = 1;
if (semop(sem_s, &op, 1)) {
printf("Erreur op.\n");
exit(-1);
}
}
gettimeofday(&end, NULL);
op.sem_op = -1;
if (semop(sem_c, &op, 1)) {
printf("Erreur attente.\n");
exit(-1);
}
}
printf("Valeur finale SHM : %d\n", *shm);
/* detache la SHM */
if (shmdt(shm)) {
printf("Erreur détachement.\n");
exit(-1);
}
if (!server) {
/* Destruction SHM */
if (shmctl(shmid, IPC_RMID, 0)) {
printf("Erreur destruction SHM.\n");
exit(-1);
}
/* Libération sémaphore */
if (semctl(sem_s, 0, IPC_RMID, 0) || semctl(sem_c, 0, IPC_RMID, 0)) {
printf("Erreur libération sémaphore.\n");
exit(-1);
}
/* Calcul débit*/
int delta =
((end.tv_sec - begin.tv_sec) * 1000000L + end.tv_usec) - begin.tv_usec;
int debit =
(NB_ITERATION * 2 * sizeof(int) * 8) / (delta); // (delta est déjà en us)
printf("Débit calculé : %d Mb/s\n", debit);
}
printf("Fin.\n");
return 0;
}
/*
if (server) {
printf("Affectation de la valeur par le serveur.\n");
*shm = 10;
sleep(10);
printf("Nouvelle valeur lue par le serveur : %d\n", *shm);
}
else {
printf("Valeur lue par le client : %d\n", *shm);
*shm = 28;
printf("Valeur modifiée par le client : %d\n", *shm);
}
*/

174
TP/TP3/calcul.c Normal file
View file

@ -0,0 +1,174 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <pthread.h>
#include <unistd.h>
#define D 1000
/*
* TP 3
* 1) Fait et ok.
* 2) Fait et ok. On constate que la seconde méthode est plus longue.
* 3) Ça ne donne pas la bonne valeur : il faut proteger l'incrémentation par un mutex
* 4) On constate que le temps de'exécution augmente de manière exp.
*/
int V[D];
int V_plus[D];
int A[D][D];
int t_num = 0;
int compt_glob = 0;
void err_args() {
printf("[~] Usage: calcul [-m [1|2]] [-t #] [-i ##]\n");
printf("Aide :\n -i [ITÉRATIONS]\n -m [MÉTHODE]\n -t [THREAD] (max: 16)\n -v, verbose output\n");
exit(-1);
}
void * fn_thread_m1 (void * p_int) {
int nb_t = *(int *) p_int;
int lt = (D / nb_t) + 1;
int num = t_num;
++t_num;
for (int i = num * lt; i < (num+1)*lt && i < D; ++i){
for (int j = 0; j < D; ++j){
V_plus[i] += V[j] * A[i][j];
//compt_glob++;
}
}
pthread_exit(0);
}
void * fn_thread_m2 (void * p_int) {
int nb_t = *(int *) p_int;
int lt = (D / nb_t) + 1;
int num = t_num;
++t_num;
for (int j = 0; j < D; ++j){
for (int i = num * lt; i < (num+1)*lt && i < D; ++i){
V_plus[i] += A[i][j] * V[j];
//compt_glob++;
}
}
pthread_exit(0);
}
int main (int argc, char **argv) {
// On parse les arguments
int c;
extern char *optarg;
extern int optind;
int method = -1;
int nb_t = -1;
int ite = -1;
int v = 0; //verbose
while ((c = getopt(argc, argv, "m:t:i:v")) != -1) {
switch (c) {
case 'm':
method = atoi(optarg);
if (method != 1 && method != 2) err_args();
break;
case 't':
nb_t = atoi(optarg);
if (nb_t > 16) err_args();
break;
case 'i':
ite = atoi(optarg);
break;
case 'v':
v = 1;
break;
default:
err_args();
break;
}
}
if (method < 0 || nb_t < 0 || ite < 0) err_args();
printf("Lancement du programme...\nMéthode %d, %d thread(s) et %d itération(s)\n", method, nb_t, ite);
//Fichier de sauvegarde
FILE* fichier = NULL;
fichier = fopen("calcul.txt", "w");
fprintf(fichier, "Méthode %d - %d thread(s) - %d itération(s)\n", method, nb_t, ite);
//On initialise les tableaux
//srand(time(NULL));
if (!v) goto no_verbose1;
srand(0);
for (int i = 0; i < D; ++i){
V[i] = (rand() % 20) - 10;
V_plus[i] = 0;
for (int j = 0; j < D; ++j)
A[i][j] = (rand() % 20) - 10;
}
printf("Tableaux initialisés : \nV(0) = [ ");
for (int i = 0; i < D; ++i)
printf("%d, ", V[i]);
printf("]\n");
printf("A = [\n");
for (int i = 0; i < D; ++i){
for (int j = 0; j < D; ++j)
printf("%d, ", A[i][j]);
printf("\n");
}
printf("]\n");
no_verbose1:
;
struct timeval begin, end;
gettimeofday(&begin, NULL);
pthread_t threads[nb_t];
for (int it = 0; it < ite; ++it){
// Lancement des threads en fonction de la méthode
for (int j = 0; j < nb_t; ++j) {
if (method == 1) pthread_create(&threads[j], NULL, fn_thread_m1, (void*) &nb_t);
else pthread_create(&threads[j], NULL, fn_thread_m2, (void*) &nb_t);
}
// On attend que tout les threads finissent leur partie
for (int i = 0; i < nb_t; ++i) pthread_join(threads[i], NULL);
for (int i = 0; i < D; ++i) {V[i] = V_plus[i]; V_plus[i] = 0;}
t_num = 0;
// On affiche le vecteur calculé
if (!v) goto no_verbose2;
printf("V(%d) = [ ", it + 1);
for (int i = 0; i < D; ++i)
printf("%d, ", V[i]);
printf("]\n");
no_verbose2:;
}
gettimeofday(&end, NULL);
printf("Time: %ld microseconds\n", ((end.tv_sec - begin.tv_sec)*1000000L + end.tv_usec) - begin.tv_usec);
printf("Nombre d'opération arithmétique : %d\n", compt_glob);
printf("Enregistrement...");
fprintf(fichier, "Temps d'exécution : %ld\n", ((end.tv_sec - begin.tv_sec)*1000000L + end.tv_usec) - begin.tv_usec);
fclose(fichier);
printf("fait.\n");
return 0;
}