Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include "generator.h"
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <string.h>
int main(int argc, char *argv[]) {
/* * ANALYSE DES ARGUMENTS
* Détermine le rôle du programme (Client, Serveur ou Local)
* pour décider s'il faut activer les fonctions réseau (sockets).
*/
int is_server = (argc > 1 && strcmp(argv[1], "server") == 0);
int is_client = (argc > 1 && strcmp(argv[1], "client") == 0);
int use_socket = (is_server || is_client);
int fd = -1;
int *shared_mem = MAP_FAILED;
struct timeval start, end;
double t_rand, t_rand48;
/* * MISE EN PLACE DE LA MÉMOIRE PARTAGÉE (SHM)
* 1. shm_open : crée ou ouvre un objet de mémoire partagée POSIX.
* 2. ftruncate : définit la taille physique du segment.
* 3. mmap : projette ce segment dans l'espace d'adressage du processus.
*/
printf("Initialisation Mémoire Partagée (%zu octets)...\n", SIZE);
fd = shm_open(SHM_NAME, O_CREAT | O_RDWR, 0600);
if (fd == -1) { perror("shm_open"); exit(1); }
ftruncate(fd, SIZE);
shared_mem = mmap(NULL, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (shared_mem == MAP_FAILED) { perror("mmap"); close(fd); exit(1); }
/* * PHASE 1 : GÉNÉRATION MULTI-PROCESSUS (RAND_R)
* Utilisation de fork() pour paralléliser la génération.
* Chaque fils travaille sur une portion spécifique de la mémoire partagée.
*/
printf("\n PHASE 1 : Génération avec rand_r() [%d processus]...\n", NB_PROCESSUS);
gettimeofday(&start, NULL);
for (int i = 0; i < NB_PROCESSUS; i++) {
if (fork() == 0) {
size_t s = (size_t)i * NB_ALEATOIRES_PAR_PROC;
size_t c = (i == NB_PROCESSUS - 1) ? (NB_ALEATOIRES_TOTAL - s) : NB_ALEATOIRES_PAR_PROC;
generate_numbers(shared_mem, s, c, 0);
exit(0);
}
}
/* Synchronisation : le père attend la fin de tous ses processus fils */
for (int i = 0; i < NB_PROCESSUS; i++) wait(NULL);
gettimeofday(&end, NULL);
t_rand = get_elapsed_time(start, end);
/* Analyse statistique et export des données de la phase 1 */
Stats res_rand = analyze_data(shared_mem, NB_ALEATOIRES_TOTAL, "RAND_R", t_rand);
printf("Sauvegarde CSV (Rand)... ");
write_to_csv("rand.csv", shared_mem, NB_ALEATOIRES_TOTAL);
printf("\nTerminé.\n");
/* * PHASE 2 : GÉNÉRATION MULTI-PROCESSUS (DRAND48_R)
* Même logique de parallélisme, mais utilise l'algorithme 48-bit
* pour comparer les performances et la qualité statistique.
*/
printf("\n PHASE 2 : Génération avec drand48_r() [%d processus]...\n", NB_PROCESSUS);
gettimeofday(&start, NULL);
for (int i = 0; i < NB_PROCESSUS; i++) {
if (fork() == 0) {
size_t s = (size_t)i * NB_ALEATOIRES_PAR_PROC;
size_t c = (i == NB_PROCESSUS - 1) ? (NB_ALEATOIRES_TOTAL - s) : NB_ALEATOIRES_PAR_PROC;
generate_numbers(shared_mem, s, c, 1);
exit(0);
}
}
for (int i = 0; i < NB_PROCESSUS; i++) wait(NULL);
gettimeofday(&end, NULL);
t_rand48 = get_elapsed_time(start, end);
/* Analyse statistique et export des données de la phase 2 */
Stats res_rand48 = analyze_data(shared_mem, NB_ALEATOIRES_TOTAL, "DRAND48_R", t_rand48);
printf("Sauvegarde CSV (Drand48)... ");
write_to_csv("rand48.csv", shared_mem, NB_ALEATOIRES_TOTAL);
printf("\nTerminé.\n");
/* * COMMUNICATION RÉSEAU
* Si le mode socket est activé, transmet les résultats (Stats)
* au partenaire distant (Serveur <-> Client).
*/
if (use_socket) {
printf("\n Établissement de la connexion socket...\n");
communicate_with_socket(is_server,
res_rand.time, res_rand48.time,
res_rand.std_dev, res_rand48.std_dev,
res_rand.throughput, res_rand48.throughput,
res_rand.max_occ, res_rand.min_occ);
}
/* * NETTOYAGE DES RESSOURCES
* Libère la projection mémoire et ferme le descripteur.
*/
if (shared_mem != MAP_FAILED) munmap(shared_mem, SIZE);
if (fd != -1) close(fd);
/* * Seul le serveur ou le mode local supprime définitivement
* le segment shm de la RAM pour éviter les fuites de ressources.
*/
if (is_server || !use_socket) {
shm_unlink(SHM_NAME);
printf("\n Segment mémoire partagée supprimé du système.\n");
}
printf(" Fin du programme. Fichiers CSV conservés.\n");
return 0;
}