This repository has been archived by the owner on May 13, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
master_worker.c
151 lines (121 loc) · 4.48 KB
/
master_worker.c
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#if defined HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include "myassert.h"
#include "master_worker.h"
// Bibliothéques ajoutés
#include <unistd.h> // Pour: write, read, close, execv
#include <string.h> // Pour: sprintf
#include <stdbool.h> // Pour: bool
/**********************************************
Pour les tubes anonymes
**********************************************/
//============ MANIPULATION DE TUBES ANONYMES ============
// Fournit le côté lecture d'une pipe entrée en paramètre
int readingSidePipe(int pipe[2])
{
int ret = close(pipe[1]);
myassert(ret != -1, "La fermeture du côté écriture d'un tube anonyme s'est mal effectuée");
return pipe[0];
}
// Fournit le côté écriture d'une pipe entrée en paramètre
int writingSidePipe(int pipe[2])
{
int ret = close(pipe[0]);
myassert(ret != -1, "La fermeture du côté lecture d'un tube anonyme s'est mal effectuée");
return pipe[1];
}
// Ferme les file descriptor entrés en paramètre
void closeFD(int fd_prev, int fd_next, int fd_master)
{
// Ferme les fd et teste s'ils sont bien fermés
int ret;
ret = close(fd_prev);
myassert(ret != -1, "La fermeture d'un FD d'une pipe anonyme s'est mal effectuée");
if (fd_next != NO_NEXT) // On vérifie qu'il y a bien un tube suivant avant de le libérer
{
ret = close(fd_next);
myassert(ret != -1, "La fermeture d'un FD d'une pipe anonyme s'est mal effectuée");
}
ret = close(fd_master);
myassert(ret != -1, "La fermeture d'un FD d'une pipe anonyme s'est mal effectuée");
}
//============ UTILISATION DE TUBES ANONYMES ============
// Fonction général d'envoie d'une donnée par un tube anonyme
static void sendData(int fd, int data)
{
// Envoie la donnée par le tube entré en paramètre
int ret = write(fd, &data, sizeof(int));
myassert(ret != -1, "L'écriture d'une donnée dans un tube ne s'est pas bien déroulé");
}
// Fonction général de reception d'une donnée par un tube anonyme
static int receiveData(int fd)
{
// Lecture de la donnée par le tube entré en paramètre
int data;
int ret = read(fd, &data, sizeof(int));
myassert(ret != -1, "La lecture d'une donnée par un tube a échoué");
// Retourne la donnée qui vient d'être lu
return data;
}
//-------------------------------------------------------------------------------------
// Permet au master d'envoyer un nombre au premier worker
void masterNumberToCompute(int fd, int number)
{
sendData(fd, number);
}
// Permet au worker de recevoir le nombre à traiter
int workerNumberToCompute(int fd)
{
return receiveData(fd);
}
//-------------------------------------------------------------------------------------
// Permet au worker de dire au master que le nombre envoyé est un nombre premier
void workerIsPrime(int fd, int is_prime)
{
sendData(fd, is_prime);
}
// Permet au master de savoir si le nombre envoyé au(x) worker(s) est un nombre premier
int masterIsPrime(int fd)
{
return receiveData(fd);
}
//-------------------------------------------------------------------------------------
// Permet au worker d'envoyer un nombre au worker suivant
void workerToNextWorker(int fd, int number)
{
sendData(fd, number);
}
/**********************************************
Pour les workers
**********************************************/
// Pour créer un worker
void createWorker(int prime_number, int previous_pipe, int master_pipe)
{
printf("Creation du worker qui a pour charge le nombre premier %d\n", prime_number);
// On déclare les chaines de caractéres qui vont
// être envoyé en argument de l'exec, on sur-dimmenssionne
// les tableaux mais sans mettre un nombre exorbitant puisque
// le max_int en C a 10 chiffres (11 avec le moins)
char *argv[5]; // Arguments de l'exec
char MtoW[12];
char WtoM[12];
char prime[12];
// On transforme les int en chaine de caractére qu'on met
// dans les tabelaux qu'on vient de déclarer ci-dessus
sprintf(prime, "%d", prime_number);
sprintf(MtoW, "%d", previous_pipe);
sprintf(WtoM, "%d", master_pipe);
// On intialise les arguments de l'exec
argv[0] = "worker";
argv[1] = prime;
argv[2] = MtoW;
argv[3] = WtoM;
argv[4] = NULL;
// On fait l'exec
execv(argv[0], argv);
// Normalement le programme ne va pas jusque là, sinon on lève une erreur
perror("Problème avec l'exec lors de la création d'un worker");
}