• No se han encontrado resultados

Polimorfismo 2. Nº Mat. Calificación. class One: public Base { void ph1(){cout << "b ";} void ph2(){cout << "d ";} };

N/A
N/A
Protected

Academic year: 2021

Share "Polimorfismo 2. Nº Mat. Calificación. class One: public Base { void ph1(){cout << "b ";} void ph2(){cout << "d ";} };"

Copied!
12
0
0

Texto completo

(1)

Problema de ADOO (1er Parcial, 10 puntos - 30 minutos)

Dado el siguiente código con su correspondiente salida por consola, se

pide:

1. Diagrama Clase de Diseño, indique los patrones empleados (2.5

puntos).

2. Diagrama de secuencia de la presentación de los resultados en

consola (2.5 puntos).

3. Implementación de las clases One y Two (2.5 puntos).

4. Terminar el código de la función main() (2.5 puntos).

1

Polimorfismo

2.

3

4

#include <iostream> using namespace std; class Base{

void a(){cout << "a ";} void c(){cout << "c ";} void e(){cout << "e ";}

virtual void ph1() = 0; virtual void ph2() = 0; public: void execute(){ a(); ph1(); c(); ph2(); e(); } }; int main(){ Base *array[2];

array[0]= new One;

array[1]= new Two;

// Añadir código return 0; } /////////////////////////// Resultado de la consola /////////////////////////// a b c d e a 2 c 4 e

class One: public Base {

void ph1(){cout << "b ";} void ph2(){cout << "d ";} };

class Two: public Base {

void ph1(){cout << "2 ";} void ph2(){cout << "4 ";} };

// Añadir código

for (int i = 0; i < 2; i++){ array[i]->execute();

cout << '\n'; }

for (int i = 0; i < 2; i++) delete array[i];

(2)
(3)

Problema de SSOO (1º Parcial 15 puntos - 45 minutos)

Dado el siguiente código:

#define TAM_BUFF 10

int main(int argc, char* argv[]) {

pid_t pid1, pid2, tub1[2], tub2[2]; int fd=0; int leidos; char buffer[TAM_BUFF]; pipe(tub1); pipe(tub2); pid1=fork(); if (pid1==0){ close(tub1[1]); pid2 = fork(); if (pid2 == 0){ close(tub1[0]); close(tub2[1]);

leidos = read(tub2[0], buffer, TAM_BUFF); while (leidos >0){

write(1, buffer, leidos);

leidos = read(tub2[0], buffer, TAM_BUFF); }

close(tub2[0]); }

else {

close(tub2[0]);

leidos = read(tub1[0], buffer, TAM_BUFF); while (leidos >0){

write (tub2[1], buffer, leidos);

leidos = read(tub1[0], buffer, TAM_BUFF); } close(tub1[0]); close(tub2[1]); } } else { close(tub1[0]); close(tub2[0]); close(tub2[1]); fd = open(“datos.txt”, O_RDONLY); leidos = read(fd, buffer, TAM_BUFF); while (leidos > 0) {

write(tub1[1], buffer, TAM_BUFF); leidos = read(fd, buffer, TAM_BUFF); } close(tub1[1]); close(fd); } exit(0); }

a- (4 puntos) Dibuje el diagrama jerárquico de procesos resultante de la ejecución del programa

anterior, dibujando además la conexión de los procesos entre tuberías de los procesos.

b- (3 puntos) Si el fichero “datos.txt” contiene la cadena de caracteres “abcdefgh”, y ejecutamos el

programa anterior teniendo permisos de lectura, justificar qué se imprimiría por la salida estándar.

c- (2 puntos) Si el fichero “datos.txt” contiene la cadena de caracteres “abcdefgh”, y ejecutamos el

programa anterior NO teniendo permisos de lectura, justificar qué se imprimiría por la salida

estándar.

d- (2 puntos) Si el fichero “datos.txt” no existe y ejecutamos el programa anterior, justificar qué se

imprimiría por la salida estándar.

e- (4 puntos) Modifique el código original para que el proceso inicial asociado al main(), antes de

ejecutar el exit() espere por la finalización del proceso con pid pid1, estableciendo adicionalmente

un temporizador de 5 segundos, por si dicho proceso (pid1) tarda más de ese tiempo en finalizar. Si

llega la señal asociada al temporizador, debe matar al proceso pid1 y terminar.

(4)

Solución

a.

b. El proceso padre será capaz de abrir y leer el fichero “datos.txt”, leyendo todos los datos del fichero en la

primera llamada read() y escribiendo estos datos en la tubería tub1. El proceso hijo leerá dichos datos y los

escribirá en la tubería tub2. Finalmente, el proceso nieto leerá estos datos y los escribirá por la salida

estándar. Por tanto, por la salida estándar se escribirá la cadena “abcdegfh”.

c. Dado que no se tiene permisos de lectura, la llamada open() fallará y fd tomará el valor -1. Al intentar

leer de -1 la llamada read() también devolverá el valor -1. El padre cerrará la tubería. El hijo no leerá

ningún dato y cerrará la tubería tub2 también. El nieto no leerá ningún dato y finalizará, no habiendo

impreso nada por la salida estándar.

d. En este caso ocurrirá lo mismo que en el apartado anterior, dado que la llamada open() fallará al no

existir el fichero, devolviendo un -1. A partir de ahí, el comportamiento del programa será el mismo.

e. Habría que añadir el siguiente código:

pid_t pid1, pid2; // Variables globales para que puedan ser vistas por las dos funciones

// Función de tratamiento de la alarma void tratar_alarma(int signal)

{

//Mata al proceso pid1, que es el proceso hijo kill(pid1, SIGKILL);

}

int main(int argc, char* argv[]) {

struct sigaction accion;

…..

accion.sa_handler = &tratar_alarma; sigaction(SIGALRM, &accion, NULL); alarm(5); // Establece el temporizador waitpid(pid1,NULL,0);

…..

}

Hijo

Nieto

Padre

tub2

tub1

datos.txt

stdout: 1

(5)

Problema de ADOO (2º Parcial, 10 puntos - 30 minutos)

Se desea realizar un programa para calcular las comisiones de

las extracciones bancarias.

En esta primera versión se han implementado dos tipos de

comisiones: i) Comisión internacional, si el código BIC (Bank

International Code) de la extracción indica que es un banco

extranjero, con una comisión del 40% sobre la cantidad a

extraer. ii) Comisión fija de 5€ por extracción.

La solución debe permitir que en un futuro se implementen

nuevos tipos de comisiones y se puedan variar dinámicamente.

Se pide:

1. Diagrama de Clases de Diseño e indique los patrones

empleados (5 puntos).

2. Implementación de las clases Extraccion, IComision,

ComisionInternacional, ComisionFija (5 puntos).

1. Patrón Estrategia #include <iostream> using namespace std; class BIC { char * codigo; public: BIC(char * codigo); bool esCodigoInternacional(); }; class Extraccion{…}; class IComision{…}; class ComisionInternacional{…}; class ComisionFija{…}; int main() { float cantidad;

cout <<"\nCantidad a extraer: "; cin >> cantidad;

BIC banco("CAIXESBB888");

Extraccion miExtraccion(cantidad, banco); cout << "\nTotal de la operación: " << miExtraccion.getTotal() <<" euros.";

return 0; }

/////////////////////////// Ejecución del programa /////////////////////////// Cantidad a extraer: 100 Extraccion internacional

(6)
(7)

Problema de SSOO (2º Parcial, 15 puntos - 45 minutos)

a) Comunicación interproceso (5 puntos)

El siguiente código es un programa (controladorTelescopio.c) que simula el control de la posición de un

telescopio astronómico, definida por dos coordenadas: declinación (DEC) y ascensión recta (RA).

Se pide desarrollar un programa independiente que permita controlar la posición de la cúpula donde se

encuentra ubicado el telescopio, con las siguientes condiciones:

La cúpula sigue al telescopio, es decir, calcula su movimiento en función de la posición en la que se

encuentre el telescopio.

Para conseguir lo anterior, el controlador del telescopio debe enviar al controlador de la cúpula su

posición (RA y DEC) una vez ha terminado su movimiento.

La comunicación entre ambos programas debe realizarse mediante tuberías.

El movimiento de la cúpula también se debe simular mediante un sleep(x segundos).

El esquema propuesto, por tanto, es el siguiente:

No es necesario añadir los #include de las diferentes librerías.

Además se pide modificar el controlador del telescopio para añadir la parte de comunicación entre ambos

procesos.

b) Comunicación por sockets

A continuación se pide modificar el controlador del telescopio para que sea una aplicación cliente-servidor con

dos hilos de ejecución tal y como indica el siguiente esquema:

-

Monitor: es un hilo que lee cada 5 segundos la última posición del telescopio (variables compartidas RA

y DEC) y se las envía al controlador de la cúpula desarrollado por medio de tuberías en el apartado a).

-

Servidor: es un hilo servidor que atiende las peticiones que le llegan mediante sockets con la posición a

la que se desea mover el telescopio, simulándolo de nuevo con un sleep() y modificando las variables

globales con la posición actual.

El cliente envía mediante sockets al servidor las coordenadas RA y DEC a las que quiere mover el telescopio,

tal y como se ve en el código dado a continuación.

1 int main(int argc,char* argv[]) { 2

3 float ra=-1, dec=-1; 4

5 while(ra != 0 && dec != 0) {

6 printf("Indica las coordenadas para mover el telescopio\n"); 7 scanf("%f %f", &ra, &dec);

8 printf("Moviendo a RA=%.2f, DEC=%.2f\n", ra, dec); 9 sleep(2); // Se simula que tarda 2 segundos en moverse 10 }

11 printf("El telescopio se ha aparcado\n"); 12 }

Controlador

Cúpula

Controlador

Telescopio

Tubería

Controlador

Cúpula

Controlador

Telescopio

Tubería

Cliente

Socktets

Hilo Monitor

Hilo Servidor

(8)

Se pide:

b.1) Completar el main y variables compartidas (2 puntos).

b.2) Completar en pseudocódigo el hilo Servidor para que atienda a las peticiones del cliente dado (3 puntos).

Para el pseudocódigo puede utilizarse simplemente los nombres de los servicios: accept, bind, listen, connect,

socket, write, read y close.

b.3) Completar el código del hilo Monitor (3 puntos).

Se adjunta el esqueleto del controlador del telescopio a completar y el código completo del cliente.

c) Sincronización (2 puntos)

Indica si en el código del controlador del telescopio del apartado b) es posible que ocurra alguna condición de

carrera. Razona la respuesta.

//ESQUELETO DEL CONTROLADOR DEL TELESCOPIO float ra = 0.0, dec = 0.0;

// Thread que lee los datos del telescopio // cada 5 segundos y se los envía al // controlador de la cúpula

void Monitor(void) { }

// Thread servidor que atiende peticiones // para mover el telescopio. Comunicacion // por sockets void Servidor(void) { } int main() { pthread_t th1, th2; pthread_create(&th1,NULL,Servidor,NULL); pthread_create(&th2,NULL, Monitor,NULL); pthread_join(th1, NULL); pthread_join(th2, NULL); }

// CODIGO COMPLETO DEL CLIENTE int main() {

int sd;

struct sockaddr_in server_addr; struct hostent *hp; int num[2]; sd = socket(AF_INET, SOCK_STREAM, 0); if (sd < 0){ printf("Error en socket\n"); return 1; } hp = gethostbyname (IP_SERVIDOR); if (hp == NULL){

printf("Error en la llamada gethostbyname\n"); return 1;

}

memcpy (&(server_addr.sin_addr), >h_addr, hp->h_length);

server_addr.sin_family = AF_INET; server_addr.sin_port = htons(4200);

if (connect(sd, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0) {

printf("Error en la llamada connect"); return 1; } printf("Introduce RA:\n"); scanf("%d", &num[0]); num[0]=htonl(num[0]); printf("Introduce DEC:\n"); scanf("%d", &num[1]); num[1]=htonl(num[1]);

write(sd, (char *) num, 2 *sizeof(int)); close (sd);

return 0; }

(9)

SOLUCIÓN

a) Código fuente:

https://bitbucket.org/rcedazo/sii-1718/src/master/ej2-ssoo-jul18/

// ControladorCupula.c

int main(int argc,char* argv[]) { int tuberia; char mensaje[100]; tuberia = open("/tmp/Tuberia",O_RDONLY); while(1) { read(tuberia, mensaje, 100);

printf("Girando cupula a: %s\n", mensaje); }

close(tuberia); return 0; }

// ControladorTelescopio.c

1 int main(int argc,char* argv[]) { 2

3 float ra=-1, dec=-1;

int tuberia; // Tuberia FIFO para comunicarse con la cupula char mensaje[100];

mkfifo("/tmp/Tuberia",0777); // Se crea la tuberia

tuberia=open("/tmp/Tuberia",O_WRONLY); // Se abre en modo escritura 4

5 while(ra != 0 && dec != 0) {

6 printf("Indica las coordenadas para mover el telescopio\n"); 7 scanf("%f %f", &ra, &dec);

8 printf("Moviendo a RA=%.2f, DEC=%.2f\n", ra, dec); 9 sleep(2); // Se simula que tarda 2 segundos en moverse

sprintf(mensaje,"%.2f %.2f", ra, dec); write(tuberia, mensaje, strlen(mensaje)+1); 10 }

11 printf("El telescopio se ha aparcado\n"); close(tuberia);

unlink("/tmp/Tuberia"); 12 }

(10)

b)

float ra = 0.0, dec = 0.0; int tuberia;

// Thread que lee los datos del telescopio cada 5 segundos void Monitor(void) {

char mensaje[100]; while(1) {

printf("Lee los datos del telescopio\n");

// El monitor devuelve los ultimos valores de RA y DEC // No consulta la montura para obtener los valores

printf("Telescopio en la posicion RA=%.2f, DEC=%.2f\n", ra, dec);

// Se envian las coordenadas al controlador del telescopio // a traves de la tuberia FIFO

sprintf(mensaje,"%.2f %.2f", ra, dec); write(tuberia, mensaje, strlen(mensaje)+1); sleep(5); // Se lee cada 5 segundos

} }

int main() {

pthread_t th1, th2;

// Se crea la tuberia para mkfifo("/tmp/Tuberia",0777); // Se abre la tuberia

tuberia=open("/tmp/Tuberia",O_WRONLY); pthread_create(&th1, NULL, Servidor, NULL); pthread_create(&th2, NULL, Monitor, NULL); pthread_join(th1, NULL); pthread_join(th2, NULL); close(tuberia); unlink("/tmp/Tuberia"); return 0; }

(11)

Se incluye el código en C pero para la solución se puede utilizar pseudocódigo tal como indica el enunciado.

// Thread servidor que atiende peticiones para mover el telescopio // Comunicacion por sockets

void Servidor(void) {

struct sockaddr_in server_addr,client_addr; int sd, sc, res, size;

int num[2];

sd = socket(AF_INET, SOCK_STREAM, 0); if (sd < 0) {

printf("Error en la llamada socket\n"); return 1; } server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = inet_addr(IP_SERVIDOR); server_addr.sin_port = htons(4200); int on=1; setsockopt(sd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));

if (bind(sd, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0){ printf("Error en la llamada bind\n");

return 1; } listen(sd, 5); size = sizeof(client_addr); while (1){

printf("Servidor del telescopio esperando cliente...\n"); sc = accept(sd, (struct sockaddr *)&client_addr, &size); if (sc < 0){

printf("Error en accept\n"); break;

}

/* recibe la petición, dos números enteros */ if (read(sc, (char *) num, 2 *sizeof(int)) < 0){ printf("Error en read\n");

pthread_exit(1); }

/* los datos se transforman del formato de red al del computador */ ra = ntohl(num[0]);

dec = ntohl(num[1]);

printf("Empieza movimiento a RA=%.2f, DEC=%.2f\n", ra, dec); sleep(10); // Se actualizan ra y dec

printf("Fin del movimiento\n"); }

close (sd); pthread_exit(1); }

(12)

c) La condición de carrera podría ocurrir en el acceso a las variables RA y DEC, ya que el Monitor podría estar

leyendo la posición del telescopio mientras el Servidor las cambia porque recibe la petición de algún cliente.

Referencias

Documento similar

Las personas solicitantes deberán incluir en la solicitud a un investigador tutor, que deberá formar parte de un grupo de investigación. Se entiende por investigador tutor la

La solución que se ha planteado, es que el paso o bien se hiciese exclusivamente por el adarve de la muralla, o que una escalera diese acceso por la RM evitando la estancia (De

Imparte docencia en el Grado en Historia del Arte (Universidad de Málaga) en las asignaturas: Poéticas del arte español de los siglos XX y XXI, Picasso y el arte español del

Ambos conjuntos tienen igual número de elementos, dado que existe entre ellos la siguiente correspondencia biunívoca: (a,b,c,d,e,f) &lt;-&gt; (a,b-1,c-2,d-3,e-4,f-5) dónde

Pero, al fin y al cabo, lo que debe privar e interesar al sistema, es la protección jurisdiccional contra las ilegalidades de la Administración,221 dentro de las que se contemplan,

Dado un espazo topol´ oxico, denominado base, e dado un espazo vec- torial para cada punto de dito espazo base, chamaremos fibrado vectorial ´ a uni´ on de todos estes

22 Enmarcado el proyecto de investigación de I+D «En clave femenina: música y ceremonial en las urbes andaluzas durante el reinado de Fernando VII (1808-1833)» (Plan Andaluz

Licenciado en Letras Españolas Licenciado en Lengua Inglesa Total Títulos Profesionales:. GRADOS