-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathX1_ChaveinteCabanilla_Parte2.c
358 lines (313 loc) · 10.3 KB
/
X1_ChaveinteCabanilla_Parte2.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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
#include<stdio.h>
#include<pthread.h>
#include <semaphore.h>
#include<stdlib.h>
#include<stdbool.h>
// MIGUEL CHAVEINTE GARCIA DNI:70840164A
// JHON STEEVEN CABANILLA ALVARADO DNI:71056366M
//Declaracion tipos de datos
struct datoBuffer
{
char m_dec;
char m_uni;
char m_letras;
bool m_bFin;
};
struct datoVector
{
int m_procesados;
int m_correctos;
int m_indMax;
};
struct tNodo
{
int m_pos;
char m_char;
struct tNodo *m_sig;
};
//Declaracion funciones
void inserta(int pos, char car);
void recorre(FILE* fichEscritura);
//Variables Globales
struct datoBuffer *buffer1;
struct tNodo* lista = NULL;
struct datoVector *vectorDato;
int tamBuffer;
int numConsumidores;
int indexC=0;
int hiloterminado;
//Semaforos
sem_t hay_dato;
sem_t hay_espacio;
sem_t mutexC;
sem_t hayDatoparaLector;
sem_t hayEspacioparaLector;
sem_t mutexLista;
//Hilo productor
void *productor(void *arg)
{
//Fichero abierto en el main
FILE *fichero=(FILE *) arg;
char cadena [7];
struct datoBuffer dato;
int index = 0; //sig posicion a llenar
while(fgets(cadena, 100, fichero) != NULL)
{
int cuentaCaracteres=0;
int i=0;
while (cadena[i] != 13) {
cuentaCaracteres++;
i++;
}
if (cuentaCaracteres == 3)
{
dato.m_dec = cadena[0];
dato.m_uni = cadena[1];
dato.m_letras = cadena[2];
dato.m_bFin = false;
//Escribir en el Buffer circular
sem_wait(&hay_espacio);
buffer1[index] = dato;
index = (index + 1) % tamBuffer;
sem_post(&hay_dato);
}
}
//Al ser el ultimo token llevar señal de fin
sem_wait(&hay_espacio);
dato.m_bFin = true;
buffer1[index] = dato;
sem_post(&hay_dato);
pthread_exit(NULL);
}
//Hilo consumidor
void *consumidor(void *arg)
{
int *id=(int *)arg;
//Variables para escritura en fichero
int numProcesados;
int numCorrectos;
int maximo;
struct datoVector datoProcesado;
struct datoBuffer dato;
int posicion;
while(true)
{
//Leer del Buffer circular
sem_wait(&hay_dato);
sem_wait(&mutexC);
dato = buffer1[indexC];
numProcesados ++;
if(dato.m_bFin != true) {
indexC = (indexC + 1) % tamBuffer;
}
else{
sem_post(&mutexC);
sem_post(&hay_dato);
break;
}
sem_post(&mutexC);
sem_post(&hay_espacio);
//Validacion de token valido
if(dato.m_dec >= 'd' && dato.m_dec <= 'm')
{
posicion = (((int)dato.m_dec) - 100) *10;
}
if(dato.m_uni >= 'F' && dato.m_uni <= 'O')
{
posicion=posicion+(((int)dato.m_uni) -70);
numCorrectos ++;
if (posicion > maximo)
maximo = posicion;
//Inserta nodo a la lista enlazada con semaforo para no ser interrumpido
sem_wait(&mutexLista);
inserta(posicion,dato.m_letras-1);
sem_post(&mutexLista);
}
}
datoProcesado.m_procesados = numProcesados;
datoProcesado.m_correctos = numCorrectos;
datoProcesado.m_indMax = maximo;
//Guardamos los datos del hilo en vector
vectorDato[*id] = datoProcesado;
sem_wait(&hayEspacioparaLector);
hiloterminado = *id;
sem_post(&hayDatoparaLector);
}
//Hilo lector
void *lector(void *arg)
{
FILE *fichEscritura=(FILE *)arg;
struct datoVector datoSalida;
int indexL;
int procesadosTotales=0;
int procesadosCorrectos=0;
int indexSupremo=0;
for (int i=0; i<numConsumidores; i++) //Por cada consumidor
{
sem_wait(&hayDatoparaLector);
indexL = hiloterminado;
sem_post(&hayEspacioparaLector);
datoSalida = vectorDato[indexL];
//Escritura en fichero por cada hilo y sus atributos.
fprintf(fichEscritura,"%s%d\n","HILO ",indexL);
fprintf(fichEscritura,"\t%s%d\n","Tokens procesados: ",datoSalida.m_procesados);
fprintf(fichEscritura,"\t%s%d\n","Tokens correctos: ",datoSalida.m_correctos);
fprintf(fichEscritura,"\t%s%d\n","Tokens incorrectos: ",datoSalida.m_procesados-datoSalida.m_correctos);
fprintf(fichEscritura,"\t%s%d\n","Max index: ",datoSalida.m_indMax);
procesadosTotales+=datoSalida.m_procesados;
procesadosCorrectos+=datoSalida.m_correctos;
if(datoSalida.m_indMax>indexSupremo)
{
indexSupremo=datoSalida.m_indMax;
}
}
fprintf(fichEscritura,"%s\n","Resultado final (los que procesa el consumidor final) ");
fprintf(fichEscritura,"\t%s%d\n","Tokens procesados: ",procesadosTotales);
fprintf(fichEscritura,"\t%s%d\n","Tokens correctos: ",procesadosCorrectos);
fprintf(fichEscritura,"\t%s%d\n","Tokens incorrectos: ",procesadosTotales-procesadosCorrectos);
fprintf(fichEscritura,"\t%s%d\n","Max index: ",indexSupremo);
if(procesadosCorrectos-indexSupremo==1)
{
fprintf(fichEscritura,"\t%s\n","Mensaje: Correcto!");
//Se escribe el mensaje descifrado.
recorre(fichEscritura);
}
else
{
fprintf(fichEscritura,"\t%s\n","Mensaje: Incorrecto :(");
}
}
//Funcion que recorre la lista enlazada y escribe en fichero el char correspondiente
void recorre(FILE* fichEscritura)
{
struct tNodo* index = lista; //Indice auxiliar para recorrer la lista
fprintf(fichEscritura,"%s","Mensaje traducido:");
while(index != NULL)
{
fprintf(fichEscritura, "%c", index -> m_char);
index = index -> m_sig;
}
fprintf(fichEscritura,"\n");
}
//Funcion que inserta un nuevo nodo a la lista enlazada en la posicion correspondiente
void inserta(int pos, char car)
{
struct tNodo* index = lista;
struct tNodo* anterior = NULL;
while(index != NULL && pos > index->m_pos)
{
anterior = index;
index = index -> m_sig;
}
struct tNodo* nodo = (struct tNodo*)malloc(sizeof(struct tNodo)); //Nodo auxiliar
if (nodo == NULL)
{
printf("ERROR:No se pudo reservar correctamente la memoria\n");
exit(-1);
}
nodo -> m_pos = pos;
nodo -> m_char = car;
//Actualizar nodos
if (anterior == NULL) //Caso especial en caso de que el bucle no de ninguna vuelta
lista = nodo;
else
anterior -> m_sig = nodo;
nodo -> m_sig = index;
}
//Main
int main(int argc, char* argv[])
{
//Comprobacion de numero de parametros correcto
if (argc != 5)
{
printf("ERROR:Numero de parametros invalido\n");
return -1;
}
FILE* fichEntrada;
fichEntrada = fopen(argv[1], "r");
//Comprobacion de fichero vacio
if(fichEntrada==(FILE *) NULL)
{
printf("ERROR:El fichero no pudo abrirse para lectura\n");
return -1;
}
FILE* fichSalida;
fichSalida = fopen(argv[2], "wt");
//Comprobacion de fichero vacio
if(fichSalida==(FILE *) NULL)
{
printf("ERROR:El fichero no pudo abrirse para escritura\n");
return -1;
}
//Leer tamaño del Buffer y convertirlo en un entero
if (sscanf(argv[3], "%d", &tamBuffer) != 1)
{
printf("ERROR:El tamaño del buffer no es entero");
return -1;
}
//validar que el tamBuffer es >0
if (tamBuffer <= 0)
{
printf("ERROR:El tamaño del Buffer no puede ser negativo ni igual a 0\n");
return -1;
}
if (sscanf(argv[4], "%d", &numConsumidores) != 1)
{
printf("ERROR:El numero de consumidores no es entero");
return -1;
}
if(numConsumidores<=0)
{
printf("ERROR:El numero de consumidores no puede ser negativo ni igual a 0\n");
return -1;
}
//Reservar memoria de forma dinamica
buffer1 = (struct datoBuffer *)malloc(tamBuffer*sizeof(struct datoBuffer));
if (buffer1 == NULL)
{
printf("ERROR:No se pudo reservar correctamente la memoria\n");
return -1;
}
vectorDato = (struct datoVector *)malloc(numConsumidores*sizeof(struct datoVector));
if (vectorDato == NULL)
{
printf("ERROR:No se pudo reservar correctamente la memoria\n");
return -1;
}
//Inicializacion de semaforos
sem_init (&hay_dato, 0, 0);
sem_init (&hay_espacio, 0, tamBuffer);
sem_init(&mutexC,0,1);
sem_init (&hayDatoparaLector, 0, 0);
sem_init (&hayEspacioparaLector, 0, 1);
sem_init(&mutexLista,0,1);
//Declaracion de hilos: productor y consumidor
pthread_t tproductor;
pthread_t tconsumidor[numConsumidores];
pthread_t tlector;
int id [numConsumidores];
//Creacion de hilos
pthread_create(&tproductor, NULL, productor,(void *)fichEntrada);
pthread_create(&tlector, NULL, lector, (void *)fichSalida);
for(int i =0;i<numConsumidores;i++){
id[i]=i;
pthread_create(&tconsumidor[i],NULL,*consumidor,(void *) &id[i]);
}
pthread_join(tproductor, NULL);
for(int i =0;i<numConsumidores;i++){
pthread_join(tconsumidor[i],NULL);
}
pthread_join(tlector, NULL);
//Liberar memoria
free(buffer1);
free(vectorDato);
fclose(fichEntrada);
fclose(fichSalida);
sem_destroy(&hay_dato);
sem_destroy(&hay_espacio);
sem_destroy(&mutexC);
sem_destroy(&hayDatoparaLector);
sem_destroy(&hayEspacioparaLector);
sem_destroy(&mutexLista);
return 0;
}