Está en la página 1de 9

Fibonacci Resuelto.

pdf

Anónimo

Programación Concurrente y Tiempo Real

2º Grado en Ingeniería Informática

Escuela Superior de Informática


Universidad de Castilla-La Mancha

Reservados todos los derechos.


No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
Escuela Superior de Informática
Universidad de Castilla-La Mancha
Programación Concurrente y Tiempo Real

No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
Examen Práctica Semáforos y Memoria Compartida

Examen de Semáforos y Memoria Compartida

APELLIDOS: ___________________________________________________________________
NOMBRE: ___________________________________________ DNI: ______________________

Indicaciones:
Calificación
● Quite de la mesa cualquier libro, apunte y/o teléfono móvil.
● Debe anotar su solución por escrito en el espacio disponible en este cuestionario.
● Cuando tenga una solución al ejercicio muéstrela al profesor (compilación + ejecución).
● Tiempo para realizar el examen: 1 hora y 30 minutos.

Reservados todos los derechos.


Enunciado
Construya, utilizando ANSI C estándar, dos ejecutables que modelen el siguiente sistema de
procesamiento concurrente. La simulación constará de un proceso cliente que creará un vector
que contendrá los n primeros elementos de la sucesión de Fibonacci1. A continuación, la suma de
estos n elementos será calculada concurrentemente por un conjunto de procesos de sumatorio.

El usuario ejecutará un proceso cliente indicándole tres parámetros:


./exec/cliente <n_elem_fib> <n_proc_sumatorio> <tamsv>

Este proceso cliente creará un vector con tantos elementos como se indique en n_elem_fib,
representando cada uno de ellos al elementos correspondiente de la sucesión de Fibonacci. En
n_proc_sumatorio se indicará el número de procesos de sumatorio que se lanzarán para su
cálculo. Finalmente, tamsv será el tamaño máximo de cada subvector (cada proceso sumatorio
calculará un sumatorio parcial cuyo resultado actualizará convenientemente el campo result de
una variable de memoria compartida).

Los procesos sumatorio atenderán peticiones de cálculo de sumatorios parciales hasta que el
cliente les envíe la señal de terminación (señal SIGINT). En cada petición, el proceso les
indicará el índice de inicio y fin de cada subvector, actualizando éstos en el campo result el
resultado parcial del sumatorio.

Consideraciones:
• No es obligatorio realizar la comprobación de errores.
• Preste especial atención a lograr el máximo paralelismo posible en la solución.

1 La sucesión de Fibonacci es una sucesión infinita de número naturales que comienza con 0 y 1 y, a partir de éstos,
cada elemento es la suma de los dos anteriores (0, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 143, ...)

Página 1 de 7

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-1218278
Escuela Superior de Informática
Universidad de Castilla-La Mancha
Programación Concurrente y Tiempo Real
Examen Práctica Semáforos y Memoria Compartida

Resolución
Utilice el código fuente suministrado a continuación como plantilla para resolver el ejercicio. Este
código fuente no contiene errores y no debe ser modificado (salvo la inicialización de los semáforos
en el proceso ). Únicamente debe incorporar su código en la sección indicada.

No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
 Indique a continuación el valor de inicialización de los semáforos (código en .c):

Línea de Código Semáforo Uso Inicialización


192 rdenlista Despierta a un proceso de sumatorio
193 rdenleida Indica al cliente que la orden fue leída

194 in El sumatorio del subvector fue


calculado
Exclusión mutua para actualizar el
195 utex campo result

Reservados todos los derechos.


Test de Resultado Correcto
Una vez resuelto el ejercicio, si ejecuta el comando ./exec/ 10 3 3 el resultado debe ser
algo similar a (naturalmente cambiará el PID de los procesos sumatorio y probablemente el orden
de atención de las peticiones):
[PID 30146] Ini 0 Fin 2 ResParcial 2
[PID 30145] Ini 3 Fin 5 ResParcial 10
[PID 30144] Ini 6 Fin 8 ResParcial 42
[PID 30146] Ini 9 Fin 9 ResParcial 34

Resultado: 88

0 1 1 2 3 5 8 13 21 34

[PID 30146] [PID 30145] [PID 30144] [PID 30146]


Ini 0 Fin 2 Ini 3 Fin 5 Ini 6 Fin 8 Ini 9 Fin 9
R. Parcial 2 R. parcial 10 R. parcial 42 R. parcial 34

+ + + +
88
vdatos.result

 Complete el resultado obtenido de la ejecución con la siguiente lista de argumentos:


./exec/ 80 10 5

Resultado: _ __

Página 2 de 7

Tenemos lo que nos faltaba: Imprime tus apuntes al mejor precio y recíbelos en casa
a64b0469ff35958ef4ab887a898bd50bdfbbe91a-1218278
Escuela Superior de Informática
Universidad de Castilla-La Mancha
Programación Concurrente y Tiempo Real
Examen Práctica Semáforos y Memoria Compartida

Esqueleto de Código Fuente


A continuación se muestra el esqueleto de código fuente para resolver el ejercicio.

makefile
1 DIROBJ = obj/
2 DIREXE = exec/
3 DIRHEA = include/
4 DIRSRC = src/

No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
5
6 CFLAGS := -I$(DIRHEA) -c -Wall
7 LDLIBS := -lpthread -lrt -lm
8 CC := gcc
9
10 all : dirs sumatorio
11
12 dirs:
13 mkdir -p $(DIROBJ) $(DIREXE)
14
15 : $(DIROBJ) .o $(DIROBJ)semaforoI.o
16 $(CC) -o $(DIREXE)$@ $^ $(LDLIBS)
17
18 sumatorio: $(DIROBJ)sumatorio.o $(DIROBJ)semaforoI.o
19 $(CC) -o $(DIREXE)$@ $^ $(LDLIBS)
20
21 $(DIROBJ)%.o: $(DIRSRC)%.c
22 $(CC) $(CFLAGS) $^ -o $@
23
24 clean :
25 rm -rf *~ core $(DIROBJ) $(DIREXE) $(DIRHEA)*~ $(DIRSRC)*~
26
27 test: # Salida: 88
28 ./exec/ 10 3 3
29

Reservados todos los derechos.


30 :
31 ./exec/ 80 10 5

globaltp.h
32 #define _XOPEN_SOURCE
33 #define _XOPEN_SOURCE_EXTENDED
34 #include <stdio.h>
35 #include <errno.h>
36 #include <string.h>
37 #include <stdlib.h>
38 #include <unistd.h>
39 #include <fcntl.h>
40 #include <math.h>
41 #include <signal.h>
42 #include <sys/mman.h>
43 #include <sys/stat.h>
44 #include <sys/types.h>
45
46 #include "semaforoI.h"
47
48 #define SEMORD I "s_ord "
49 #define SEMORD "s_ord
50 #define SEMFIN "s_fin"
51 "
#define MUTEX "s_mutex"
52
53 #define MEM "mc_ "
54 #define MEMORDEN "mc_orden"
55
56 #define MAXARRAY 1000
57
58 struct atos {
59 long long result;
60 long long v[MAXARRAY];
61 };
62
63 struct rden {
64 int inicio;
65 int fin;
66 };
67
68 enum TipoProceso {SUMATORIO};
69
70 struct roceso {
71 enum TipoProceso tipo; /* Tipo del proceso */
72 pid_t pid; /* PID del proceso hijo */
73 };

Página 3 de 7

Tenemos lo que nos faltaba: Imprime tus apuntes al mejor precio y recíbelos en casa
a64b0469ff35958ef4ab887a898bd50bdfbbe91a-1218278
Escuela Superior de Informática
Universidad de Castilla-La Mancha
Programación Concurrente y Tiempo Real

No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
Examen Práctica Semáforos y Memoria Compartida

semaforoI.h
74 #ifndef __SEMAFOROI_H__
75 #define __SEMAFOROI_H__
76
77 #include <semaphore.h>
78
79 /* Crea un semáforo POSIX */
80 sem_t *crear_sem (const char *name, unsigned int valor);
81 /* Obtiene un semáforo POSIX (ya existente) */
82 sem_t *get_sem (const char *name);
83 /* Cierra un semáforo POSIX */
84 void destruir_sem (const char *name);
85 /* Incrementa el semáforo */
86 void signal_sem (sem_t *sem);
87 /* Decrementa el semáforo */
88 void wait_sem (sem_t *sem);
89
90 #endif

semaforoI.c

Reservados todos los derechos.


91 #include <stdio.h>
92 #include <errno.h>
93 #include <string.h>
94 #include <stdlib.h>
95 #include <unistd.h>
96 #include <fcntl.h>
97
98 #include <semaforoI.h>
99
100 sem_t *crear_sem (const char *name, unsigned int valor) {
101 sem_t *sem;
102
103 sem = sem_open(name, O_CREAT, 0644, valor);
104 if (sem == SEM_FAILED) {
105 fprintf(stderr, "Error al crear el sem. <%s>: %s\n",
106 name, strerror(errno));
107 exit(EXIT_FAILURE);
108 }
109
110 return sem;
111 }
112
113 sem_t *get_sem (const char *name) {
114 sem_t *sem;
115
116 sem = sem_open(name, O_RDWR);
117 if (sem == SEM_FAILED) {
118 fprintf(stderr, "Error al obtener el sem. <%s>: %s\n",
119 name, strerror(errno));
120 exit(EXIT_FAILURE);
121 }
122
123 return sem;
124 }
125
126 void destruir_sem (const char *name) {
127 sem_t *sem = get_sem(name);
128
129 if ((sem_close(sem)) == -1) {
130 fprintf(stderr, "Error al cerrar el sem. <%s>: %s\n",
131 name, strerror(errno));
132 exit(EXIT_FAILURE);
133 }
134
135 if ((sem_unlink(name)) == -1) {
136 fprintf(stderr, "Error al destruir el sem. <%s>: %s\n",
137 name, strerror(errno));
138 exit(EXIT_FAILURE);
139 }
140 }
141
142 void signal_sem (sem_t *sem) {
143 if ((sem_post(sem)) == -1) {
144 fprintf(stderr, "Error al modificar el sem.: %s\n",
145 strerror(errno));
146 exit(EXIT_FAILURE);
147 }
148 }
149
150 void wait_sem (sem_t *sem) {
151 if ((sem_wait(sem)) == -1) {
152 fprintf(stderr, "Error al modificar el sem. : %s\n",
153 strerror(errno));
154 exit(EXIT_FAILURE);
155 }
156 }

Página 4 de 7

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-1218278
Escuela Superior de Informática
Universidad de Castilla-La Mancha
Programación Concurrente y Tiempo Real
Examen Práctica Semáforos y Memoria Compartida

157 #include "globaltp.h"


158
159 /* Funciones de soporte */
160 long long fibonacci (int n, long long *v);
161 void controlador (int senhal);
162 void liberarRecursos (void);
163 void finalizarProcesos (void);
164
165 int ; /* Número de procesos */
166 struct roceso * pids; /* Tabla de procesos **/

No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
167
168 int main(int argc, char *argv[]) {
169 struct atos * ;
170 struct rden *orden;
171 pid_t pid;
172
173 int shmMC , shmMCOrden;
174 sem_t * rden ista, * rden eida, * in;
175 int i, n lem , n , ;
176 int , = 0, = 0;
177
178 /* Instalación del manejador de Control-C */
179 if (signal(SIGINT, controlador) == SIG_ERR) {
180 fprintf(stderr, "Error al instalar manejador en %s\n", argv[0]);
181 exit(EXIT_FAILURE);
182 }
183
184 n = atoi(argv[1]); /* Numero elementos del vector */
185 n = atoi(argv[2]); /* Numero de procesos sumatorio */
186 = atoi(argv[3]); /* Tamano maximo del subvector */
187
188 = n ;
189 pids = malloc(sizeof(struct roceso ) * ( )); /* Tabla de procesos */
190

Reservados todos los derechos.


191 /* Creación de semáforos y v.m.c. */
192 rden ista = crear_sem(SEMORD , );
193 rden eida = crear_sem(SEMORD , );
194 in = crear_sem(SEMFIN, );
195 crear_sem(MUTEX, );
196
197 shmMC = shm_open(MEM , O_CREAT | O_RDWR, 0644);
198 ftruncate(shmMC , sizeof(struct atos ));
199 = mmap(NULL, sizeof(struct atos ), PROT_READ | PROT_WRITE,
MAP_SHARED, shmMC , 0);
200
201 shmMCOrden = shm_open(MEMORDEN, O_CREAT | O_RDWR, 0644);
202 ftruncate(shmMCOrden, sizeof(struct orden));
203 orden = mmap(NULL, sizeof(struct rden ), PROT_READ | PROT_WRITE,
MAP_SHARED, shmMCOrden, 0);
204
205 /* Cálculo de la sucesión de Fibonacci */
206 for (i = 0; i < n ; i++) {
207 ->v[i] = fibonacci(i, ->v);
208 }
209 ->result = 0;
210
211 /* Creación de procesos sumatorio */
212 for (i = 0; i < n ; i++) {
213 switch (pid = fork()) {
214 case -1 : /* Código de error */
215 fprintf(stderr, "Error en creación de proceso\n");
216 finalizarProcesos();
217 liberarRecursos();
218 exit(EXIT_FAILURE);
219 break;
220 case 0 : /* Proceso hijo */
221 if (execl("./exec/sumatorio", "sumatorio", NULL) == -1) {
222 fprintf(stderr, "Error al usar execl()\n");
223 finalizarProcesos();
224 liberarRecursos();
225 exit(EXIT_FAILURE);
226 }
227 break;
228 default: /* Proceso padre */
229 pids[i].tipo = SUMATORIO;
230 pids[i].pid = pid;
231 }
232 }
233 printf ("Se han lanzado %d procesos SUMATORIO\n", n );
234 sleep(1); /* Esperamos 1 seg. */
235
236
237
238
239
240
241
242
243

Página 5 de 7

Tenemos lo que nos faltaba: Imprime tus apuntes al mejor precio y recíbelos en casa
a64b0469ff35958ef4ab887a898bd50bdfbbe91a-1218278
Escuela Superior de Informática
Universidad de Castilla-La Mancha
Programación Concurrente y Tiempo Real
Examen Práctica Semáforos y Memoria Compartida

244 n = ceil(n / (float) tam ); /* Numero de subvectores a calcular */


245
246 while ( < n ) {
247 orden->inicio = ( * tam );
248 orden->fin = orden->inicio + tam -1;
249 if (orden->fin > (n -1)) orden->fin = n -1;
250 ++;
251
252 signal_sem( rden ista);
253 wait_sem( rden eida);
254 }
255

No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
256 /* Esperar a que todos los subvectores hayan sido calculados */
257 while (n < n ) {
258 wait_sem( in);
259 n ++;
260 }
261
262 printf ("\nResultado: %lld \n", ->result);
263
264 close(shmMC );
265 close(shmMCOrden);
266 finalizarProcesos();
267 liberarRecursos();
268
269 return ;
270 }
271
272 long long fibonacci (int n, long long *v) {
273 if (n<2) return (n); else return (v[n-1] + v[n-2]);
274 }
275
276 /* Manejador de señal SIGINT */
277 void controlador (int senhal) {
278 printf("\nFin del programa (Control + C)\n");
279 finalizarProcesos();

Reservados todos los derechos.


280 liberarRecursos();
281 exit(EXIT_SUCCESS);
282 }
283
284 /* Liberación de recursos */
285 void liberarRecursos (void) {
286 printf("\n----- Liberando recursos ----- \n");
287 free( pids);
288 destruir_sem(MUTEX); destruir_sem(SEMFIN);
289 destruir_sem(SEMORD ); destruir_sem(SEMORD );
290 shm_unlink(MEM ); shm_unlink(MEMORDEN);
291 }
292
293 /* Terminación de procesos hijos */
294 void finalizarProcesos (void) {
295 int i;
296
297 printf("\n----- Finalización de procesos hijos vivos ----- \n");
298 for (i = 0; i < ; i++) {
299 if ( pids[i].pid != 0) { /* Proceso hijo vivo */
300 switch ( pids[i].tipo) {
301 case SUMATORIO:
302 printf("Finalizando proceso SUMATORIO [%d]...\n", pids[i].pid);
303 break;
304 }
305 kill( pids[i].pid, SIGINT);
306 }
307 }
308 }

Página 6 de 7

Tenemos lo que nos faltaba: Imprime tus apuntes al mejor precio y recíbelos en casa
a64b0469ff35958ef4ab887a898bd50bdfbbe91a-1218278
Escuela Superior de Informática
Universidad de Castilla-La Mancha
Programación Concurrente y de Tiempo Real

No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
Examen Práctica Semáforos y Memoria Compartida

324 #include "globaltp.h"


325
326 int main (int argc, char *argv[]) {
327 int shmMC , shmMCOrden;
328 struct TDatos_t *datos;
329 struct TOrden_t *orden;
330 sem_t * rden ista, * rden eida, * in, * utex;
331 int i, indiceInicio, indiceFin;
332 ;
333
334
335 shmMC = shm_open(MEM , O_RDWR, 0644);
336 datos = mmap(NULL, sizeof(struct TDatos_t), PROT_READ | PROT_WRITE, MAP_SHARED,
shmMC , 0);
337
338 shmMCOrden = shm_open(MEMORDEN, O_RDWR, 0644);
339 orden = mmap(NULL, sizeof(struct TOrden_t), PROT_READ | PROT_WRITE, MAP_SHARED,
340 shmMCOrden, 0);
341
342

Reservados todos los derechos.


343 rden ista = get_sem(SEMORDENLISTA);
344 rden eida = get_sem(SEMORDENLEIDA);
345
346 in = get_sem(SEMFIN);
347 utex = get_sem(MUTEX);
348
349

 Incluya aquí el bucle para atender peticiones (Longitud aprox. ≈ 5 Líneas de código)
Muestre en pantalla información sobre el PID del proceso que ha calculado cada subvector, el inicio y el fin y el resultado

while (1) {
350 wait_sem ( rdenLista);
351
352 indiceInicio = orden->inicio;
353 indiceFin = orden->fin;
354
355 signal_sem ( rdenLeida);
356
357
358
359
360
361 for (i = indiceInicio; i <= indiceFin; i++) {
362
363 datos-> [i];
364 }
365
366
367
368 wait_sem( utex);
369
370 datos-> = ;
371 signal_sem( utex);
372
373
374
375
376 printf ("[PID %d] Ini %d Fin %d ",
377 getpid(), indiceInicio, indiceFin );
378
379
380 signal_sem( in);
381
382 }

383 return EXIT_SUCCESS;


384 }

Paseo de la Universidad 4 | 13071 Ciudad Real | Telf: (+34) 926295300 | Fax: (+34) 926295354

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-1218278

También podría gustarte