Está en la página 1de 8

PCTR_P2_B02_Semaforos_MC_Plantil...

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
Ampliación de Sistemas Operativos

No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
Examen Laboratorio Práctica 2 · 22 Noviembre 2010

Examen de Laboratorio
Práctica 2. Semáforos y Memoria Compartida

APELLIDOS: ___________________________________________________________________
NOMBRE: ___________________________________________ TITULACIÓN: ❑ ITIS ❑ ISI

Indicaciones:
Calificación
● Esta parte del examen se valorará sobre 4 puntos. No se permiten libros o apuntes.
● Es imprescindible que el programa compile sin errores y que el resultado obtenido sea
correcto para superar esta parte del examen.
● 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).

Reservados todos los derechos.



● Tiempo para realizar el examen: 1 hora y 30 minutos.

Enunciado
Construya, utilizando ANSI C estándar, dos ejecutables que modelen el siguiente sistema. La simulación
constará de un proceso cliente que cargará una cadena de la línea de órdenes (que definirá una matriz) y
encargará su procesamiento a procesos de dos tipos: preprocesador y traductor. El usuario ejecutará
un proceso cliente indicándole tres parámetros:
./cliente <cadena> <nfilas> <ncolumnas> <npreproc>
Este proceso cliente cargará una matriz definida en cadena empleando el punto como separador de
elementos de tantas filas y columnas como se indique en nfilas y ncolumnas. Este array estará formado
por números enteros que tendrán que procesar los preprocesadores y el proceso de traducción. En npreproc 
se indicará el número de procesos preprocesador que se lanzarán para preprocesar la matriz. Los
preprocesadores se encargarán de sumar 1 a cada elemento de la matriz en las filas pares (se considera la
primera fila 0 como par), y de dividir entre 2 el valor de cada elemento de la matriz en filas impares. El
proceso cliente se encargará de repartir el preprocesamiento de la matriz por filas, asignando en cada
momento una fila a un proceso preprocesador que esté ocioso, hasta que se asignen todas las filas de la
matriz. Cuando todas las filas de la matriz hayan sido preprocesadas, el cliente llamará al único proceso
traductor del sistema que se encargará de traducir cada número de la matriz en un carácter ASCII. La
correspondencia de traducción se resume en la siguiente tabla (la última fila de la tabla es la correspondencia
del carácter con su código ASCII necesario para realizar la traducción). Si el número entero a traducir es
mayor que 52, se traducirá siempre como un espacio en blanco.

Entero 1 2 ... 25 26 27 28 ... 51 52 >52


Traducción a b ... y z A B ... Y Z (Espacio blanco)
Código ASCII 97 98 ... 121 122 65 66 ... 89 90 32

Los procesos atenderán peticiones de traducción y preproceso hasta que el cliente les envíe la señal de
terminación. En cada petición a los preprocesadores el proceso cliente les indicará la fila a traducir y el tipo
de preproceso (sumar uno o dividir entre dos). El traductor trabajará directamente con la matriz completa.

Consideraciones:
• Por simplificar, en la solución se utiliza un array unidimensional para almacenar la matriz. Es responsabilidad
del programador posicionarse adecuadamente donde comienza cada fila.
• No realice comprobación de errores en los parámetros de la utilidad cliente. El proceso cliente se encargará de
enviar la señal de terminación a los procesos de traducción y al proceso de puntuación cuando éstos hayan
calculado el sumatorio final.
• Preste especial atención a lograr el máximo paralelismo posible en la solución.

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

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-1218276
Escuela Superior de Informática
Universidad de Castilla-La Mancha
Ampliación de Sistemas Operativos
Examen Laboratorio Práctica 2 · 22 Noviembre 2010

Test de Resultado Correcto


Una vez resuelto el ejercicio, si ejecuta el cliente con los siguientes argumentos (se define una matriz de
2 filas y 5 columnas, y se lanzan dos preprocesadores), se debe obtener el resultado indicado abajo:
./cliente 33.14.11.0.92.78.42.28.8.30 2 5 2
Mensaje decodificado: 
­­­­­­­­­­­­­­­­­­­­­ 

No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
Hola 
Mundo 
 Complete el resultado obtenido de la ejecución con la siguiente lista de argumentos
./cliente 33.0.18.90.0.15.17.14.4.2.8.30.120.10.24.120.4.23.0.12.4.13.60.60 3 8 1 
   Mensaje decodificado: 
   ­­­­­­­­­­­­­­­­­­­­­ 

Reservados todos los derechos.


Resolución
Utilice el código fuente suministrado a continuación como plantilla para resolver el ejercicio. Este código
fuente no contiene errores. Escriba únicamente en los espacios habilitados en este formulario (marcados con
un recuadro y el icono ) el código que aporta a la solución del problema.

Esqueleto de Código Fuente


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

makefile
1 LNKFLAGS = ­ggdb ­Wall ­ansi ­D_XOPEN_SOURCE ­lm 
2 CC = gcc 
3
4 DIROBJ = obj/ 
5 DIREXE = exec/ 
6 DIRHEA = include/ 
7 DIRSRC = src/ 
8
9 all : cliente traductor preprocesador 
10
11 clean : 
12 rm ­f *~ core $(DIROBJ)* $(DIREXE)* 
13
14 cliente : $(DIRSRC)cliente.c $(DIRHEA)globaltp.h semaforo.o 
15 $(CC) $(LNKFLAGS) ­I $(DIRHEA) ­o $(DIREXE)cliente $(DIRSRC)cliente.c $(DIROBJ)semaforo.o 
16
17 traductor : $(DIRSRC)traductor.c $(DIRHEA)globaltp.h semaforo.o 
18 $(CC) $(LNKFLAGS) ­I $(DIRHEA) ­o $(DIREXE)traductor $(DIRSRC)traductor.c $(DIROBJ)semaforo.o 
19
20 preprocesador : $(DIRSRC)preprocesador.c $(DIRHEA)globaltp.h semaforo.o 
21 $(CC) $(LNKFLAGS) ­I $(DIRHEA) ­o $(DIREXE)preprocesador $(DIRSRC)preprocesador.c $(DIROBJ)semaforo.o 

 # Completa el makefile con la regla que falta


semaforo.o : $(DIRSRC)semaforo.c $(DIRHEA)semaforo.h
$(CC) -c -o $(DIROBJ)semaforo.o $(DIRSRC)semaforo.c

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

Tenemos lo que nos faltaba: Imprime tus apuntes al mejor precio y recíbelos en casa
a64b0469ff35958ef4ab887a898bd50bdfbbe91a-1218276
Escuela Superior de Informática
Universidad de Castilla-La Mancha
Ampliación de Sistemas Operativos
Examen Laboratorio Práctica 2 · 22 Noviembre 2010

globaltp.h
22 #include <stdio.h> 
23 #include <signal.h> 
24 #include <math.h> 
25 #include <string.h> 
26 #include <stdlib.h> 
27 #include <sys/types.h> 
28 #include <unistd.h> 
29 #include <sys/time.h> 
30 #include <sys/resource.h> 

No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
31 #include <sys/wait.h> 
32 #include <sys/shm.h> 
33 #include <sys/msg.h> 
34 #include <sys/ipc.h> 
35 #include "semaforo.h" 
36
37 #define MC_MATRIZ    (key_t) 2000 
38 #define MC_ORDENP    (key_t) 2001 
39
40 #define SEM_ORDENP   (key_t) 3000 
41 #define SEM_ORDENT   (key_t) 3001 
42 #define SEM_MUTEXP   (key_t) 3002 
43 #define SEM_FINT     (key_t) 3003 
44 #define SEM_FINFILA  (key_t) 3004 
45
46 #define MAXPROC  20    /* Numero maximo de procesos de preproceso */ 
47 #define N 200          /* Numero maximo de elementos de la matriz */ 
48
49 #define PROCSUMAR 0    /* Tipo de preprocesamiento para filas pares   */ 
50 #define PROCDIVIDIR 1  /* Tipo de preprocesamiento para filas impares */ 
51
52 struct matrizdatos{ 
53   char datos[N];      /* Tamano maximo de la matriz    */ 
54   int nfil;           /* Numero de filas utilizadas    */ 

Reservados todos los derechos.


55   int ncol;           /* Numero de columnas utilizadas */ 
56 }; 
57 struct orden{ 
58   int fila;           /* Numero de fila a procesar       */ 
59   int tipo;           /* Tipo de procesamiento           */ 
60 };

semaforo.h
61 int getsem(int nClaveSem); 
62 int initsem(int nClaveSem, int nValor); 
63 int delsem(int nIdSem); 
64 int waitsem(int nIdSem); 
65 int signalsem(int nIdSem);

semaforo.c
66 #include <sys/types.h> 
67 #include <sys/ipc.h> 
68 #include <sys/sem.h> 
69
70 int getsem(int nClaveSem){ return (semget(nClaveSem, 1, IPC_CREAT | 0666)); } 
71 int initsem(int nClaveSem, int nValor){ 
72   int nIdSem; 
73   
74   nIdSem = getsem(nClaveSem); 
75   if (nIdSem == ­1) return ­1; 
76   semctl(nIdSem, 0, SETVAL, nValor); 
77   return nIdSem; 
78 } 
79 int delsem(int nIdSem){ return (semctl(nIdSem, 0, IPC_RMID, 0)); } 

 # Implemente las operaciones que faltan (waitsem y signalsem)


int operationsem(int nIdSem, int op){
struct sembuf sb; sb.sem_num = 0; sb.sem_op = op; sb.sem_flg = 0;
return (semop(nIdSem, &sb, 1));
}

int waitsem(int nIdSem) { return (operationsem(nIdSem, -1)); }


int signalsem(int nIdSem) { return (operationsem(nIdSem, 1)); }

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

Tenemos lo que nos faltaba: Imprime tus apuntes al mejor precio y recíbelos en casa
a64b0469ff35958ef4ab887a898bd50bdfbbe91a-1218276
Escuela Superior de Informática
Universidad de Castilla-La Mancha
Ampliación de Sistemas Operativos

No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
Examen Laboratorio Práctica 2 · 22 Noviembre 2010

cliente.c
80 #include "globaltp.h" 
81
82 void creamatriz(struct matrizdatos *m, char *arg, int nfil, int ncol) { 
83   int i=0;  char *cad; 
84
85   m­>datos[0] = atoi(strtok(arg, ".")); 
86   while ((cad = strtok(NULL, ".")) != NULL) { 
87     m­>datos[++i] = atoi(cad); 
88   } 
89   m­>nfil = nfil; 
90   m­>ncol = ncol; 
91 } 
92
93 void imprimematriz(char *datos, int filas, int columnas) { 
94   int i, j; 
95   printf ("Mensaje decodificado:\n­­­­­­­­­­­­­­­­­­­­­\n"); 
96   for (i=0; i<filas; i++) { 
97     for (j=0; j<columnas; j++) putchar(datos[i*columnas+j]); 
98     putchar('\n'); 
99   } 

Reservados todos los derechos.


100 } 
101
102 int main(int argc, char *argv[]){ 
103
104   int idMatriz, idOrdenP;    /* Identificadores Memoria Compartida  */ 
105   struct matrizdatos *m;     /* Punteros a la Memoria Compartida    */ 
106   struct orden *ordenP;      /* Orden para Preprocesadores          */ 
107
108   int semOrdenP, semOrdenT, semMutexP, semFinT, semFinFila; 
109   int nfilas, ncolumnas, nproc, i; 
110
111   int vpid[MAXPROC];         /* Vector de PIDs de procesos lanzados */ 
112
113   nfilas = atoi(argv[2]);       /* Numero de filas de la matriz     */  
114   ncolumnas = atoi(argv[3]);    /* Numero de columnas de la matriz  */  
115   nproc = atoi(argv[4]);        /* Numero de procesos de preproceso */ 
116
117   idMatriz = shmget(MC_MATRIZ, sizeof(struct matrizdatos), IPC_CREAT | 0666);  
118   m = (struct matrizdatos *) shmat(idMatriz, 0, 0); 
119
120   creamatriz(m, argv[1], nfilas, ncolumnas);   /* Rellena la matriz */ 
121   idOrdenP = shmget(MC_ORDENP, sizeof(struct orden), IPC_CREAT | 0666);  
122   ordenP = (struct orden *) shmat(idOrdenP, 0, 0); 
123  /* "Initsem" de los 5 semaf.: semOrdenP, semMutexP, semFinFila, semOrdenT, semFinT */ 

 # Complete el valor de inicialización de los 5 semáforos de la solución


semOrdenP = initsem(SEM_ORDENP, 0 ); /* Semaforo de orden para Preprocesadores */
semMutexP = initsem(SEM_MUTEXP, 1 ); /* Mutex de orden para Preprocesadores */
semFinFila = initsem(SEM_FINFILA, 0 ); /* Indica que se ha preprocesado una fila */
semOrdenT = initsem(SEM_ORDENT, 0 ); /* Despierta al traductor */
semFinT = initsem(SEM_FINT, 0 ); /* Espera fin de traduccion */

124   for (i=0; i<nproc; i++) { 
125     if ((vpid[i] = fork()) == 0) execl("./preprocesador", "./preprocesador", NULL); 
126   } 
127
128   if ((vpid[i] = fork()) == 0) execl("./traductor", "./traductor", NULL); 
129
130   /* Creamos ordenes de trabajo para cada preprocesador */ 
131   for (i=0; i<nfilas; i++) { 

 # Complete el código del bucle for para crear las órdenes de trabajo (filas) para
los preprocesadores

waitsem(semMutexP);
ordenP->fila = i;
if (i%2 == 0) ordenP->tipo = PROCSUMAR;
else ordenP->tipo = PROCDIVIDIR;
signalsem(semOrdenP);

132   } 

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

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-1218276
Escuela Superior de Informática
Universidad de Castilla-La Mancha
Ampliación de Sistemas Operativos
Examen Laboratorio Práctica 2 · 22 Noviembre 2010

 # Complete el código para esperar fin de preproceso de todas las filas

for (i=0; i<nfilas; i++)


waitsem(semFinFila);

No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
 # Complete el código para despertar al traductor y esperar fin de traducción

signalsem(semOrdenT); /* Despertamos al traductor */


waitsem(semFinT); /* Esperamos que acabe su trabajo */

133   imprimematriz(m­>datos, nfilas, ncolumnas);   /* Muestra resultado de traduccion */ 
134
135   for (i=0; i<nproc+1; i++) kill (vpid[i], SIGINT);         /* Matar procesos hijo */ 
136
137   shmdt(m); shmdt(ordenP);    /* Eliminamos recursos creados (memoria y semaforos) */ 
138   shmctl(idMatriz, IPC_RMID, 0);   shmctl(idOrdenP, IPC_RMID, 0);   
139   delsem(semOrdenP); delsem(semOrdenT); delsem(semMutexP); delsem(semFinT); delsem(semFinFila); 
140   return 0; 
141 }

preprocesador.c

Reservados todos los derechos.


142 #include "globaltp.h" 
143 void preprocesa (char *a, int tipo) { 
144   switch (tipo) { 
145   case PROCSUMAR: *a+=1; break; 
146   case PROCDIVIDIR: *a/=2; break; 
147   } 
148 } 
149 int main(void){ 
150   int idMatriz, idOrdenP;    /* Identificadores Memoria Compartida  */ 
151   struct matrizdatos *m;     /* Puntero a la Memoria Compartida     */ 
152   struct orden *ordenP;      /* Puntero a orden de Preprocesador    */ 
       
153   int semOrdenP, semMutexP, semFinFila;     /* Ids de Semaforos     */ 
154   int i; 

 # Defina aquí las variables extra que necesite para su solución

struct orden orden;


int j;

155   idMatriz = shmget(MC_MATRIZ, sizeof(struct matrizdatos), IPC_CREAT | 0666);  
156   m = (struct matrizdatos *) shmat(idMatriz, 0, 0); 
157   idOrdenP = shmget(MC_ORDENP, sizeof(struct orden), IPC_CREAT | 0666);  
158   ordenP = (struct orden *) shmat(idOrdenP, 0, 0); 
159   semOrdenP  = getsem(SEM_ORDENP); 
160   semMutexP  = getsem(SEM_MUTEXP); 
161   semFinFila = getsem(SEM_FINFILA); 
162   while (1) { 

 # Incluya aquí el código del bucle principal

waitsem (semOrdenP); /* Hay que hacer copia local de orden */


memcpy (&orden, ordenP, sizeof(struct orden));
signalsem (semMutexP);
for (i=0; i < (m->ncol); i++) {
j = (orden.fila*m->ncol) + i;
preprocesa(&(m->datos[j]), orden.tipo);
}
signalsem(semFinFila);

163   } return 0; 
164 }

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

Tenemos lo que nos faltaba: Imprime tus apuntes al mejor precio y recíbelos en casa
a64b0469ff35958ef4ab887a898bd50bdfbbe91a-1218276
Escuela Superior de Informática
Universidad de Castilla-La Mancha
Ampliación de Sistemas Operativos
Examen Laboratorio Práctica 2 · 22 Noviembre 2010

traductor.c
165 #include "globaltp.h" 
166 void traducir (char *a) { 
167   if (*a <= 26) *a += 96;       /* Minuscula */ 
168   else if (*a <= 52) *a += 38;  /* Mayuscula */ 
169   else *a = 32;                 /* Espacio en blanco */ 
170 } 
171 int main(void){ 
172   int idMatriz;  struct matrizdatos *m;      int semOrdenT, semFinT; 
173   int i; 

No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
174
175   idMatriz = shmget(MC_MATRIZ, sizeof(struct matrizdatos), IPC_CREAT | 0666);  
176   m = (struct matrizdatos *) shmat(idMatriz, 0, 0); 
177
178   semOrdenT  = getsem(SEM_ORDENT); 
179   semFinT    = getsem(SEM_FINT); 
180
181   while (1) { 

 # Incluya aquí el código del bucle principal

waitsem(semOrdenT);
for (i=0; i<(m->nfil*m->ncol); i++) traducir(&m->datos[i]);
signalsem(semFinT);

Reservados todos los derechos.


182   } return 0; 
183 }

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

Tenemos lo que nos faltaba: Imprime tus apuntes al mejor precio y recíbelos en casa
a64b0469ff35958ef4ab887a898bd50bdfbbe91a-1218276

También podría gustarte