Sie sind auf Seite 1von 52

Universidad de Crdoba Escuela Politcnica Superior

Ampliacin de Sistemas Operativos

3 Ingeniera Tcnica en Informtica de Sistemas

Antonio Cid Garca (i22cigaa)

Ampliacin de Sistemas Operativos

Quin es quin?

NDICE
Captulo 1: Introduccin a PVM. 3 Captulo 2: Definicin del Juego10 Captulo 3: Definicin del Problema..11 Captulo 4: Descripcin de la Solucin..12 Bibliografa.15 Anexo A: Manual de cdigo..16 Anexo B: Exclusin mutua. Algoritmo de anillos de fichas..41 Anexo C: Primitivas de PVM utilizadas43 Anexo D: Ejecucin y Salida del programa...46

Ampliacin de Sistemas Operativos

Quin es quin?

CAPTULO 1: Introduccin a PVM.


1.1. Que es PVM?
PVM (Paralel Virtual Machine, Mquina Paralela Virtual) es una herramienta software y un conjunto de libreras diseada para solucionarnos una gran cantidad de problemas asociados con la programacin paralela. Sobre todo, el monetario. Para ello, nos va a crear una nueva abstraccin, que es la mquina paralela virtual, empleando los recursos computacionales libres de todas las mquinas de la red que pongamos a disposicin de la biblioteca. Es decir, disponemos de todas las ventajas econmicas asociadas a la programacin distribuida, ya que empleamos los recursos hardware de dicho paradigma; pero programando el conjunto de mquinas como si se tratara de una sola mquina paralela, que es mucho ms cmodo. La mquina paralela virtual es una mquina que no existe, pero un API apropiado nos permite programar como si existiese. El modelo abstracto que nos permite usar el API de PVM consiste en una mquina multiprocesador completamente escalable (es decir, que podemos aumentar y disminuir el nmero de procesadores en lnea). Para ello, nos va a ocultar la red que estemos empleando para conectar nuestras mquinas, as como las mquinas de la red y sus caractersticas especficas. PVM opera sobre diferentes plataformas de UNIX y tambin de Windows 9x, la cantidad de plataformas en las que puede correr el ambiente de PVM es muy variada y abundante. PVM puede establecerse en cualquier esquema de red heterognea, sobre todo en el ambiente de Internet. A pesar de que PVM no es un estndar, es sumamente popular para realizar y desarrollar aplicaciones cientficas complejas que requieren un esquema de programacin en paralelo, dada su compatibilidad en sistemas operativos es sumamente portable y fcil de instalar, adems de que PVM consiste en un esquema pequeo de cdigo de computadora.

1.2. Ventajas y desventajas de PVM


Este planteamiento tiene numerosas ventajas respecto a emplear un supercomputador, de las cuales, las ms destacadas son:

Precio. As como es mucho ms barato un computador paralelo que el computador tradicional equivalente, un conjunto de ordenadores de mediana o baja potencia es muchsimo ms barato que el computador paralelo de potencia equivalente. Al igual que ocurrir con el caso del computador paralelo, van a existir factores (fundamentalmente, la lentitud de la red frente a la velocidad del bus del computador paralelo) que van a hacer de que sean necesarios ms ordenadores de pequea potencia que los tericos para igualar el rendimiento. Sin embargo, aun teniendo esto en cuenta, la solucin es mucho ms barata. 3

Ampliacin de Sistemas Operativos

Quin es quin?

Adems, al no ser PVM una solucin que necesite de mquinas dedicadas (es decir, el daemon de PVM corre como un proceso ms), podemos emplear en el proceso los tiempos muertos de los procesadores de todas las mquinas de nuestra red a las que tengamos acceso. Por ello, si ya tenemos una red Unix montada, el costo de tener un supercomputador paralelo va a ser cero ya disponemos de las mquinas, no tendremos que comprar nada nuevo, y adems la biblioteca PVM es software libre, por lo que no hay que pagar para usarla Disponibilidad. Todo centro de clculo tiene un mnimo de una docena de mquinas arrumbadas en una esquina, y que nadie sabe qu hacer exactamente ya con ellas. Con esa docena que hace seis aos que ya no corren ni la ltima versin del Word para Windows, podemos instalar Linux, PVM y aadirlo al supercomputador paralelo virtual que conforma las mquinas que ya tendramos en red. Tolerancia a fallos. Si por cualquier razn falla uno de los ordenadores que conforman nuestra PVM y el programa que la usa est razonablemente bien hecho. Nuestra aplicacin puede seguir funcionando sin problemas. En un caso como el nuestro, en el que la aplicacin va a estar corriendo durante meses, es crtico que la aplicacin sea tolerante a fallos. Siempre hay alguna razn por la que alguna mquina puede fallar, y la aplicacin debe continuar haciendo los clculos con aquel hardware que contine disponible. Heterogeneidad. Podemos crear una mquina paralela virtual a partir de ordenadores de cualquier tipo. PVM nos va a abstraer la topologa de la red, la tecnologa de la red, la cantidad de memoria de cada mquina, el tipo de procesador y la forma de almacenar los datos. Este ltimo punto es de extrema importancia, ya que el principal problema que tendramos en los sockets era la programacin de rutinas de conversin de formato de datos entre todos los ordenadores de la red, puesto que la codificacin, tanto de enteros como de flotantes, puede ser distinta. Por ltimo, nos permite incluir en nuestra PVM hasta mquinas paralelas. Una mquina paralela en una PVM se puede comportar tanto como una sola mquina secuencial (caso, por ejemplo, del soporte SMP de Linux) o, como ocurre en muchas mquinas paralelas, presentarse a PVM como un conjunto de mquinas secuenciales.

Adems de estas ventajas con respecto al empleo de un supercomputador, tiene muchas otras: Portabilidad. Es probablemente la librera de paso de mensajes ms portable que existe. Paralelismo Escalable. PVM permite definir cuantos procesadores puede utilizar una aplicacin, en caso de que falten procesadores, PVM realiza el trabajo en menos procesadores, recurriendo a tcnicas de procesamiento concurrente. Tolerancia a fallos a partir de aadir o borrar procesos anfitriones (Host). Fcil de Instalar y de Usar. 4

Ampliacin de Sistemas Operativos

Quin es quin?

Popular.- Es una de las libreras de paso de mensajes ms fciles y ptimas. Flexible.


o o

Esquema fcil de modificar y de configurar/definir por la mquina virtual. Control arbitrario de dependencia de estructuras. La aplicacin decide: Donde y cuando producir o terminar las tareas. Cuales mquinas se agregan o se remueven desde la mquina virtual en paralelo. Cuales tareas se pueden comunicar y/o sincronizar con otras.

Puede incorporar casi cualquier computadora que funcione bajo UNIX, (Obviamente con cuenta de acceso), para incorporarla fcilmente al esquema de la mquina virtual.

Como hemos visto el uso de PVM tiene muchas ventajas, pero tambin tiene desventajas: Nos podemos olvidar del paralelismo fuertemente acoplado. Si disponemos de una red Ethernet, simplemente la red va a dejar de funcionar para todas las aplicaciones (incluida PVM) de la cantidad de colisiones que se van a producir en caso de que intentemos paralelismo fuertemente acoplado. Si disponemos de una red de tecnologa ms avanzada; es decir, ms cara (como ATM) el problema es menor, pero sigue existiendo. La segunda desventaja es que la abstraccin de la mquina virtual, la independencia del hardware y la independencia de la codificacin tienen un coste. PVM no va a ser tan rpida como son los Sockets. Sin embargo, si el grado de acoplamiento se mantiene lo suficientemente bajo, no es observable esta diferencia. Cuenta con un esquema no estandarizado.- PVM no es un estndar (como lo es MPI). Es algo deficiente en cuanto al paso de mensajes se refiere.

1.3. Componentes de PVM


La arquitectura de PVM se compone de dos componentes que se encargan de las siguientes tareas:

Comunicaciones. Control de procesos. La interfase de programacin para el usuario.

Estas dos componentes son: el demonio PVM y las libreras de PVM. 5

Ampliacin de Sistemas Operativos


El programa demonio PVM (pvmd3)

Quin es quin?

La primera parte es el daemon, llamado pvmd. En la versin actual de PVM -la 3-, el nombre es pvmd3. El daemon ha de estar funcionando en todas las mquinas que vayan a compartir sus recursos computacionales con la mquina paralela virtual. A diferencia de otros daemons y programas del sistema, el daemon de PVM puede ser instalado por el usuario en su directorio particular (de hecho, la instalacin por defecto es as). Esto nos va a permitir hacer supercomputacin como usuarios, sin tener que discutir con el administrador de la red que programas vamos a poder ejecutar. Una vez que un usuario (o superusuario) instal en un directorio PVM, todos los usuarios pueden hacer uso de esa instalacin con el requisito de que el directorio donde est instalada PVM sea de lectura al usuario que quiera hacer uso de ella. En muchos centros de computacin, el administrador prefiere instalar l mismo PVM; con lo que, adems de evitar que un usuario pueda borrarla sin consultar a los dems, va a permitir que todos los usuarios tengan PVM instalada por defecto; y, lo que es ms importante, nosotros como administradores podremos determinar el valor de nice (prioridad del daemon) con el que va a ser lanzado el daemon pvmd3 y as, si este valor de nice es lo suficientemente alto, permite que la mquina ejecute PVM solamente en los momentos ociosos. Este daemon pvmd3 es el responsable de la mquina virtual de por s, es decir, de que se ejecuten nuestros programas para PVM y de coordinar los mecanismos de comunicacin entre mquinas, la conversin automtica de datos y de ocultar la red al programador. Por ello, una vez que PVM est en marcha, el paralelismo es independiente de la arquitectura de la mquina, y slo depende de la arquitectura de la mquina virtual creada por PVM. Esto nos va a evitar el problema que tenamos con los Sockets ya que tenamos que hacer una rutina de codificacin y otra de decodificacin, al menos, por cada arquitectura distinta del sistema. Cada usuario, arrancar el daemon como si de un programa normal se tratase, para ejecutar el cdigo de PVM. Este programa se queda residente, realizando las funciones anteriores.
Las libreras de PVM (pvmd3)

La segunda parte es la biblioteca de desarrollo. Contiene las rutinas para operar con los procesos, transmitir mensajes entre procesadores y alterar las propiedades de la mquina virtual. Toda aplicacin se ha de enlazar a la biblioteca para poderse ejecutar despus. Tendremos tres ficheros de bibliotecas: Esta librera brinda una gran cantidad de rutinas escritas en lenguaje C. Esta rutina siempre es requerida. librera adicional que se requiere en caso de que la aplicacin escrita en PVM utilice cdigo de Fortran. librera requerida en caso de usar grupos dinmicos.

Ampliacin de Sistemas Operativos

Quin es quin?

1.4. Programa en PVM


Un programa para PVM va a ser un conjunto de tareas que cooperan entre si. Las tareas se van a intercambiar informacin empleando paso de mensajes. PVM, de forma transparente al programador, nos va a ocultar las transformaciones de tipos asociadas al paso de mensajes entre mquinas heterogneas. Toda tarea de PVM puede incluir o eliminar mquinas, arrancar o parar otras tareas, mandar datos a otras tareas o sincronizarse con ellas. Cada tarea en PVM tiene un nmero que la identifica unvocamente, denominado TID (Task Identification Number). Es el nmero al que se mandan los mensajes habitualmente. Sin embargo, no es el nico mtodo de referenciar una tarea en PVM. Muchas aplicaciones paralelas necesitan hacer el mismo conjunto de acciones sobre un conjunto de tareas. Por ello, PVM incluye una abstraccin nueva, el grupo. Un grupo es un conjunto de tareas a las que nos podemos referir con el mismo cdigo, el identificador de grupo. Para que una tarea entre o salga de un grupo, basta con avisar de la salida o entrada al grupo. Esto nos va a dotar de un mecanismo muy cmodo y potente para realizar programas empleando modelos SIMD (Single Instruction, Multiple Data), en el que vamos a dividir nuestros datos en muchos datos pequeos que sean fciles de tratar, y despus vamos a codificar la operacin simple y replicarla tantas veces como datos unitarios tengamos de dividir el problema. Para trabajar con grupos, adems de enlazar la biblioteca de PVM (libpvm3.a) tenemos que enlazar tambin la de grupos (libgpvm3.a). Habitualmente para arrancar un programa para PVM, se lanzar manualmente desde un ordenador contenido en el conjunto de mquinas una tarea madre. La tarea se lanzar con el comando spawn desde un monitor de la mquina virtual, que a su vez se activar con el comando pvm. Esta tarea se encargar de iniciar todas las dems tareas, bien desde su funcin main (que va a ser la primera en ejecutarse), bien desde alguna subrutina invocada por ella. Para lanzar nuevas tareas se emplea la funcin pvm_spawn, que devolver un cdigo de error, asociado a si pudo o no crearla, y el TID de la nueva tarea. Para evitar el engorro de andar realizando transformaciones continuas de datos, PVM define clases de arquitecturas. Antes de mandar un dato a otra mquina comprueba su clase de arquitectura. Si es la misma, no necesita convertir los datos, con lo que se tiene un gran incremento en el rendimiento. En caso que sean distintas las clases de arquitectura se emplea el protocolo XDR para codificar el mensaje. Las clases de arquitectura estn mapeadas en nmeros de codificacin de datos, que son los que realmente se transmiten y, por lo tanto, los que realmente determinan la necesidad de la conversin. El modelo de paso de mensajes es transparente a la arquitectura para el programador, por la comprobacin de las clases de arquitectura y la posterior codificacin con XDR de no coincidir las arquitecturas. Los mensajes son etiquetados al ser enviados con un nmero entero definido por el usuario, y pueden ser seleccionados por el receptor tanto por direccin de origen como por el valor de la etiqueta.

Ampliacin de Sistemas Operativos

Quin es quin?

El envo de mensajes es sin bloqueo. Esto quiere decir que el que enva el mensaje no tiene que esperar a que el mensaje llegue, sino que solamente espera a que el mensaje sea puesto en la cola de mensajes. La cola de mensajes, adems, asegura que los mensajes de una misma tarea llegarn en orden entre si. Esto no es trivial, ya que empleando UDP puede que enviemos dos mensajes y que lleguen fuera de orden (UDP es un protocolo no orientado a conexin). TCP, por ser un protocolo orientado a la conexin, realiza una reordenacin de los mensajes antes de pasarlos a la capa superior, sin embargo, tiene el inconveniente que establecer las conexiones entre nodos empleando TCP supone, si tenemos n nodos, tendremos un mnimo de ($n)(n$-1) conexiones TCP activas. Provocando esto que hasta para nmeros ridculos de $n$ nos quedamos sin puertos por ste planteamiento. Establecer conexiones TCP entre procesos en lugar de entre nodos es peor todava, por las mismas razones que en el caso de los nodos. La comunicacin de las tareas con el daemon se hace empleando TCP. Esto se debe a que, al ser comunicaciones locales, la carga derivada de la apertura y cierre de un canal es muy pequeo. Adems, no vamos a tener tantas conexiones como en el caso de la conexin entre daemons, ya que las tareas no se conectan entre s ni con nada fuera del nodo, por lo que slo hablan directamente con su daemon. Esto determina que sern n conexiones TCP, que s es una cifra razonable. La recepcin de los mensajes podemos hacerla mediante primitivas con bloqueo, sin bloqueo o con un tiempo mximo de espera. PVM nos dotar de primitivas para realizar los tres tipos de recepcin. En principio nos sern ms cmodas las primitivas con bloqueo, ya que nos darn un mecanismo de sincronizacin bastante cmodo. Las de tiempo mximo de espera nos sern tiles para trabajar con ellas como si fuesen con bloqueo, mas dando soporte al hecho de que puede que el que tiene que mandarnos el mensaje se haya colgado. Por ltimo, la recepcin de mensajes mediante primitivas sin bloqueo hace de la sincronizacin un dolor de cabeza. De cualquier forma, en los tres casos anteriormente citados la misma PVM se encargar de decirnos cundo una tarea acab. Para informarnos de lo que pasa, emplea un mecanismo de eventos asncronos. PVM puede ser empleada de forma nativa como funciones en C y en C++, y como procedimientos en Fortran. Basta para ello con tomar las cabeceras necesarias (si trabajamos con C o C++); y, para los tres, enlazar con la biblioteca adecuada, que viene con la distribucin estndar. En el caso de C es libpvm3.a y en el del Fortran libfpvm3.a. Si deseamos trabajar en otros lenguajes puede ser un poco ms complejo. Si el lenguaje permite incorporar funciones nativas en lenguaje C (como es el caso, por ejemplo, de Java) no hay ningn problema; ya que podemos invocar la funcin; bien directamente si el lenguaje lo permite, bien haciendo alguna pequea rutina para adaptar el tipo de los datos, el formato de llamada a funcin o cualquiera de las restricciones que nos imponga el lenguaje que empleemos para invocar funciones en C. Hemos de destacar que toda funcin en C pvm_alguna cosa tiene como equivalente en Fortran pvmfalgunacosa, y viceversa.

Ampliacin de Sistemas Operativos

Quin es quin?

El programa PVM corresponde al intrprete de comandos de nuestra mquina virtual. Algunos de los comandos ms importantes son:

add mquina: Incorpora la mquina indicada a la mquina paralela virtual. delete mquina: Elimina la mquina indicada del conjunto de mquinas asociadas a la mquina paralela virtual. Como es lgico, no podremos eliminar la mquina desde la que estamos ejecutando el intrprete de comandos. conf: Configuracin actual de la mquina paralela virtual. ps: Listado de procesos de la mquina paralela virtual. ps -a lista todos los procesos. halt: Apaga la mquina paralela virtual. Esto significa que mata todas las tareas de PVM, elimina el daemon de forma ordenada y sale del programa pvm. help: Lista los comandos del programa. Tremendamente til en los momentos de desesperacin. id: Imprime el TID de la consola. jobs: Genera un listado de los trabajos en ejecucin. kill: Mata un proceso de PVM. mstat: Muestra el estado de una mquina de las pertenecientes a PVM. pstat: Muestra el estado de un proceso de los pertenecientes a PVM. quit: Sale de la mquina paralela virtual sin apagarla. reset: Inicializa la mquina. Eso supone matar todos los procesos de PVM salvo los programas monitores en ejecucin, limpiar las colas de mensajes y las tablas internas y pasar a modo de espera todos los servidores. setenv: Lista todas las variables de entorno del sistema. sig seal tarea: Manda una seal a una tarea. spawn: Arranca una aplicacin bajo PVM. Es un comando bastante complejo cuyas opciones veremos en una seccin aparte. trace: Actualiza o visualiza la mscara de eventos traceados. alias: Define un alias predefinido, es decir, un atajo para teclear un comando. unalias: Elimina un alias predefinido. version: Imprime la versin usada de PVM.

Ampliacin de Sistemas Operativos

Quin es quin?

CAPTULO 2: Definicin del Juego.


El presente trabajo es un simulador de una versin del popular juego Quin es quin?. El objetivo del trabajo es principalmente el familiarizarse con PVM y lograr construir un sistema distribuido que puede lograr un objetivo comn mediante la comunicacin entre ellos. La finalidad del juego original es adivinar quin aparece en la tarjeta del adversario (cada uno elige un personaje de forma aleatoria, cogiendo una carta de un mazo con todos los personajes), antes de que ste adivine tu personaje. Se suceden turnos de preguntas, en los cuales el jugador al que le corresponda, puede hacer una pregunta, del tipo s/no, al contrario, para intentar averiguar la identidad de su personaje. El jugador que ha hecho la pregunta elimina de los personajes que le quedan aquellos que no coinciden con la descripcin que se desprende de la respuesta de su oponente. El juego termina cuando uno de los jugadores piensa que sabe la identidad de la persona que aparece en la tarjeta de su oponente y la dice. Si acierta ha ganado el juego y si falla ha ganado su oponente. En esta versin pueden intervenir todos los jugadores que lo deseen, en la original slo dos. Slo hay un personaje que ser elegido aleatoriamente por el motor del juego, por lo tanto todos los jugadores intentan averiguar la identidad del mismo personaje. Los jugadores se establecen en un orden y se elige de forma aleatoria al jugador que comienza. Cuando un jugador recibe el turno realiza los mismo pasos que en el juego original; slo que en este caso las preguntas se hacen al motor del juego y no a un contrario. En vez de una pregunta, el jugador tiene la posibilidad de decir el nombre del personaje que cree que es (si ha preguntado antes tiene que esperar al siguiente turno); si adivina la identidad gana el juego y ste acaba, si falla es eliminado del juego y ste continua. En el caso de que queden dos jugadores y uno de ellos es eliminado, el juego finaliza y el ganador es el nico jugador que quede en juego. Tal y como se ve, es importante el orden de comienzo, ya que el que antes comience tiene mayor posibilidad de ganar, y el que ms tarde comience tendr menos.

10

Ampliacin de Sistemas Operativos

Quin es quin?

CAPTULO 3: Definicin del Problema.


Los problemas que se presentan en este simulador en relacin a los objetivos de esta asignatura, son los siguientes: Comunicacin. El motor del juego deber pasar continuamente informacin a los jugadores, los personajes y preguntas que crea, el jugador que comienza, las respuestas a las preguntas que formulan los jugadores, etc. Y los jugadores deben mandar sus preguntas al motor. Seccin crtica. El motor no puede atender a todos los jugadores al mismo tiempo. Por lo tanto, se debe garantizar que mientras que el motor est atendiendo a uno, los dems no le pregunten hasta que aqul sea atendido. Tambin se debe gestionar el orden en que entran a esta seccin crtica. Sincronizacin. Los jugadores y el motor deben estar sincronizados en todo momento; tanto al empezar el juego ya que deben estar todos en el mismo punto, como para el envo de informacin, ya que no se puede enviar hasta que el receptor no este listo.

11

Ampliacin de Sistemas Operativos

Quin es quin?

CAPTULO 4: Descripcin de la Solucin.


Por la naturaleza del juego hay que distribuir. Debido a esto y a los problemas antes mencionados, el uso de PVM es ideal para desarrollar la solucin al trabajo planteado. En la solucin hay dos programas diferentes. El programa juego y el programa jugador. El programa juego es el que se encarga de generar a los programas jugadores y formamos un grupo con todos los procesos, tanto con el juego como con los jugadores.

Figura 1: Creacin de los jugadores.

Antes de empezar la comunicacin se produce una sincronizacin de todos los elementos del grupo, para que todos se encuentren en el mismo punto. El proceso juego enva a los jugadores los personajes, las preguntas y el jugador que comienza, esto lo hace mediante multiemisin a todos los elementos del grupo excepto a el mismo.

Figura 2: Paso de mensajes inicial.

12

Ampliacin de Sistemas Operativos

Quin es quin?

Ahora empieza el juego en s, con las preguntas de los jugadores y las respuestas del juego. Para solucionar el problema de la seccin crtica anteriormente descrito, aplicamos el algoritmo de anillo de fichas con todos los jugadores (para ver en que consiste mirar el Anexo B). La ficha la introduce el jugador que comienza (el que escogi de forma aleatoria el padre), el resto esperar su turno, es decir que le pase la ficha el jugador que le precede. El orden del anillo corresponder con el orden en que entraron en el grupo. Pero adems de pasar el turno de unos jugadores a otros, se informar al siguiente jugador de si el juego ha concluido o no. (En la figura siguiente se representa como jugador inicial al 1, sin embargo como se sabe es aleatorio)

Figura 3: Anillo de turno.

Cuando un jugador recibe el turno, ste enva su pregunta al juego. Esta pregunta puede ser sobre una caracterstica o un personaje. Como ambos ser un nmero entero y positivo, hay que hacer algo para diferenciarlos. Para ello, cuando se pregunte por un personaje, se encriptar el mensaje, se pone negativo y se le resta 1. El jugador elegir que preguntar de la siguiente manera. Si est seguro de quien es pregunta por l. Sino, existe una probabilidad de que el jugador se arriesgue y pregunte por un personaje, en este caso el jugador elige aleatoriamente entre los personajes que no ha eliminado. Si no se arriesga, pregunta por una caracterstica, para ello elige entre las preguntas restantes. Posteriormente el juego recibe la pregunta y la procesa. Si es una pregunta sobre una caracterstica encuentra la respuesta y la enva. Si es una pregunta sobre un personaje, el juego comprueba si el jugador ha acertado o no. Si acierta es el ganador y el juego termina. Si falla el jugador es eliminado y el juego continua, a no ser que ya slo queda un jugador en este caso termina y este es el ganador. En este caso el juego enva al jugador si el juego ha acabado o no. Por ltimo el jugador recibe la respuesta. Si es a una pregunta de caractersticas, elimina los personajes que no cumplen la condicin que se saca de dicha respuesta, y tambin elimina las preguntas que ya no hacen falta hacer, ya sea por que ya han sido formuladas o porque no haga falta realizarla ya que la respuesta ya se 13

Ampliacin de Sistemas Operativos

Quin es quin?

conoce de antemano, despus pasa el turno al siguiente jugador en el anillo. Si pregunt por un personaje, recibir la informacin de si el juego ha acabado o no; si acaba termina pasa el turno al siguiente, indicando que el juego ha acabado, si no acaba, igualmente pasa el turno al siguiente, pero sin indicar que el juego ha concluido. En este ltimo caso, el jugador est eliminado y su objetivo ahora ser recibir el turno y pasarlo, sin hacer nada con l, hasta que le digan que le juego ha acabado.

Figura 4: Paso de mensajes de un jugador no eliminado en su turno.

Figura 5: Paso de mensajes de un jugador eliminado en su turno.

Tal y como se ha planteado la solucin, tenemos un modelo cliente-servidor. En el que el juego es un servidor dedicado, que espera las preguntas de los clientes, los jugadores, y las responde. Sin embargo es un servidor que en todo momento sabe quin le va a pedir servicio y por lo tanto slo espera la peticin de dicho cliente.

14

Ampliacin de Sistemas Operativos

Quin es quin?

Bibliografa
Tenembaun, Andrew S. Sistemas Operativos Distribuidos. Traducido por Palmas Velasco, scar A. Revisin tcnica de Guerrero, Gabriel. Primea Edicin. Naucalpan de Jurez, Estado de Mxico. Prentice Hall Hispanoamericana, S. A. 1996. 617 p. ISBM: 968-880-627-7. Hervs Martnez, Csar. Apuntes de PVM. Servicio de Reprografa de la Universidad de Crdoba. 2004. Ercilla Gonzlez, Carmen (i12gopac). Trabajo sobre PVM: Juego en familia. 2003-2004. Milanez Santilln, Jorge Alberto. http://iio.ens.uabc.mx/~jmilanez/escolar/ sistemas_operativos/expo-5.html. Descripcin: Teora sobre PVM. Fecha de creacin: 2004-Mar-22. ltima visita realizada: 20-Dic-2004. Olea, Ismael. http://es.tldp.org/Manuales-LuCAS/doc-cluster-computadoras/ doc-cluster-computadoras-html/node44.html. Descripcin: Teora sobre PVM. Fecha de creacin: 01-Nov-1997. ltima visita realizada: 19-Dic-2004. Http://computing.ee.ethz.ch/sepp/condor-6.3.1-to.SEPP/examples/PVM/. Descripcin: Ejemplo de programa en PVM. Fecha de creacin: 01-Nov-1997. ltima visita realizada: 20-Dic-2004.

15

Ampliacin de Sistemas Operativos

Quin es quin?

ANEXO A: Manual de cdigo


Fichero juego.h
#include <string.h> #include "pvm3.h" #define NPERS #define NPREG 32 17 /* nmero de personajes que forman parte del juego */ /* nmero de preguntas de las que consta el juego */

/* Definicin de la informacin que vamos a utilizar en el juego. Para facilitar el cmputo, se le asocian nmeros enteros */ #define HOMBRE 0 #define MUJER 1 #define RUBIO 0 #define MORENO 1 #define PELIRROJO 2 #define CASTANO 3 #define CANOSO 4 #define AZULES 0 #define VERDES 1 #define MARRONES 2 #define NEGROS 3 #define CORTO 0 #define LARGO 1 #define NO 0 #define SI 1 /* Definicin de la estructura "personaje", con todos los campo con los que vamos a caracterizar a los personajes de los que va a formar el juego */ typedef struct { char nombre[10]; int sexo; int color_pelo; int ojos; int pecas; int gafas; int long_pelo; int pendientes; int barba; } personaje; /* Nombre del personaje */ /* Sexo del personaje */ /* Color de pelo del personaje */ /* Color de ojos del personaje */ /* Si el personaje tiene pecas o no */ /* Si el personaje tiene gafas o no */ /* Longitud del pelo del personaje */ /* Si el personaje lleva pendientes o no */ /* Si el personaje tiene barba o no */

16

Ampliacin de Sistemas Operativos Fichero juego.c


#include <stdio.h> #include <stdlib.h> #include "trabajo.h" #define MAXNJUG 10 /* nmero mximo de jugadores permitidos */

Quin es quin?

void crear_personajes(personaje personajes[NPERS]); void crear_preguntas(char preguntas[NPREG][50]); int obtener_respuestas(int n_pregunta); /* FUNCIN - main DESCRIPCIN - Funcin principal del motor del juego. Crea los jugadores les pasa los personajes y las preguntas que crea y el jugador que comienza. Despus espera preguntas y las responde, si le preguntan por algn personaje comprueba si ha acertado, pudiendo finalizar el juego o continuar con l. Adems va imprimiendo en un fichero con toda la informacin relativa a la partida PARMETROS - int argc, char *argv[] VALOR DEVUELTO - Nada */ main(int argc, char *argv[]) { char preguntas[NPREG][50];/* las preguntas de las que consta el juego */ personaje personajes[NPERS]; int mytid; int *tids; int info; int i; int n_jugadores; int n_personaje; int jug_actual; int n_pregunta; int per_creido; int respuesta; int terminado=0; int *jug_eliminado; /* los personajes que forman parte del juego */ /* El TID de este motor de juego */ /* puntero que apuntar al lugar donde se almacenarn los TIDs de los procesos hijos (jugadores) */ /* variable de recogida de errores */ /* variable auxiliar */ /* nmero de jugadores que van a participar */ /* nmero del personaje elegido para el juego */ /* jugador que tiene el turno */ /* nmero de la pregunta formulada */ /* personaje que un jugador cree que es el elegido */ /* respuesta a la pregunta hecha por un jugador S o NO */ /* variable para indica si el juego ha acabado o no. Se inicializa con 0 */ /* puntero que apuntar al lugar donde se almacenar un vector para ver si un jugador est jugando o est eliminado */ /* nmero de jugadores eliminados. Inicialmente es 0 */ /* lgico del fichero */ /* Obtenmos el TID del proceso*/

int jug_eliminados=0; FILE *f; mytid = pvm_ mytid();

17

Ampliacin de Sistemas Operativos

Quin es quin?

if( mytid < 0 ) { pvm_perror("ERROR: El en el identificador del motor del juego \n"); pvm_exit(); exit(0); } if(argc == 1) { /* Si no introduce el nmero de jugadores por consola habr que pedirlos por pantalla */ do{ printf("Introduce el nmero de jugadores que van a participar (2-%d): ",MAXNJUG); scanf("%s",argv[0]); /* Almacenamos el nmero de jugadores en argv[0] para despus pasarselo a los hijos*/

n_jugadores = atoi(argv[0]); if( n_jugadores < 2 || n_jugadores > MAXNJUG ) printf("ERROR: El nmero de jugadores debe estar entre 2 y %d\n",MAXNJUG); }while( n_jugadores < 2 || n_jugadores > MAXNJUG ); } else { if(argc == 2) { n_jugadores = atoi(argv[1]); if(n_jugadores < 2 || n_jugadores > MAXNJUG) { printf("ERROR: El nmero de jugadores debe estar entre 2 y %d\n",MAXNJUG); pvm_exit(); exit(0); } } else { printf("ERROR: Nmero de argumentos no vlido\n",MAXNJUG); pvm_exit(); exit(0); } } /* Creamos el grupo donde ocupar la posicin 0; si no tiene es posicin, el grupo es errneo */ if( pvm_joingroup("juego") != 0 ) { pvm_perror("ERROR: El grupo est corrupto\n"); pvm_lvgroup( " juego " ); pvm_exit(); exit(0); } /* Ya que conocemos el nmero de jugadores, reservamos memoria para el vector TIDs y el vector jug_eliminado*/ if( (tids = (int *)(malloc(sizeof(int)*n_jugadores))) == NULL ) { printf("ERROR: No se ha podido reservar memoria correctamente\n"); pvm_lvgroup( "juego" ); pvm_exit(); exit(0); } if( (jug_eliminado = (int *)(malloc(sizeof(int)*jug_eliminados))) == NULL ) { printf("ERROR: No se ha podido reservar memoria correctamente\n"); pvm_lvgroup( "juego" ); pvm_exit(); exit(0); }

18

Ampliacin de Sistemas Operativos


info = pvm_spawn("jugador", argv, 0, "", n_jugadores, tids); /* Si no se crean todos los jugadores el juego acaba */ if( info != n_jugadores ) { for(i=0;i<info;i++) pvm_kill(tids[i]); free(tids); free(jug_eliminado); fclose(f); pvm_lvgroup( "juego" ); pvm_exit(); exit(0); }

Quin es quin?

pvm_barrier( "juego", n_jugadores+1 ); /* Sincronizamos a todos los elementos del grupo, para que la comunicacin entre el motor los jugadores sea correcta */ /* Creacin de los personajes y las preguntas de las que constar el juego */ crear_personajes(personajes); crear_preguntas(preguntas); srand ((unsigned int)time(NULL)); n_personaje = rand()%NPERS; /* Nmero aleatorio entre 0 y 31, ya que hay 32 personajes */ /* Nmero entre 1 y el nmero de jugadores que representa la posicin en el grupo del jugador que comienza */

jug_actual = rand()%n_jugadores+1; f = fopen("salida.txt","w");

fprintf(f,"Nmero de jugadores que participan en el juego: %d\n\n",n_jugadores); /* Obtenemos los TIDs de los jugadores en el orden en que estn en el grupo, que ser el orden en el juego, empezando por el elegido aleatoriamente */ for(i=0;i<n_jugadores;i++) { jug_eliminado[i] = 0; tids[i] = pvm_gettid("juego", i+1); fprintf(f,"Jugador %d: t%x\n",i+1,tids[i]); } fprintf(f,"\nLa mquina ha elegido a %s \n\n",personajes[n_personaje].nombre); fprintf(f,"Empieza el jugador %d\n\n",jug_actual); /* Iniciamos el buffer, empaquetamos y enviamos a los jugadores los personajes y las preguntas creados y el jugador que comenzar el juego. Este envo se har mediante multiemisin a todos los elementos del grupo excepto l */ pvm_initsend(PvmDataDefault); for(i=0;i<NPERS;i++) { pvm_pkstr(personajes[i].nombre); pvm_pkint(&personajes[i].sexo,1,1); pvm_pkint(&personajes[i].color_pelo,1,1); pvm_pkint(&personajes[i].ojos,1,1); pvm_pkint(&personajes[i].pecas,1,1); pvm_pkint(&personajes[i].gafas,1,1); pvm_pkint(&personajes[i].long_pelo,1,1); pvm_pkint(&personajes[i].pendientes,1,1); pvm_pkint(&personajes[i].barba,1,1); }

19

Ampliacin de Sistemas Operativos

Quin es quin?

for(i=0;i<NPREG;i++) pvm_pkstr(preguntas[i]); pvm_pkint(&jug_actual,1,1); pvm_bcast("juego",1); jug_actual--; /* Decrementamos jug_actual, para que su valor est entre 0 y n_jugadores-1 ya que los vectores empiezan desde 0 */

printf("\nLa partida se est llevando a cabo "); /* Bucle que representa el papel de motor de juego, recibiendo preguntas y respondindolas */ while( terminado == 0 ) { /* Espera la pregunta del jugador que posee el turno en cada momento */ pvm_recv(tids[jug_actual],2); pvm_upkint(&n_pregunta,1,1); /* Si el valor que llega es positivo es una pregunta, si es negativo es un personaje encriptado y habr que comprobar si ha acertado */ /* Desencripta para obtener el nmero del personaje que el jugador cree es la solucin */

if(n_pregunta < 0) { per_creido=-(1+n_pregunta);

respuesta = (per_creido == n_personaje); /* Comprueba si el jugador ha acertado o no. Ser 1 si es correcto 0 si es incorrecto */ fprintf(f,"Jugador %d => Es %s?\n",jug_actual+1,personajes[per_creido].nombre); fprintf(f,"Ordenador => %s\n\n",respuesta ? "S" : "NO"); /* Si la respuesta es 1 es que el jugador ha acertado, por lo tanto es el ganador y el juego termina; si la respuesta es 0 el jugador es eliminado */ if(respuesta) { terminado = 1; fprintf(f,"*****************************************\n"); fprintf(f,"*\tGANADOR JUGADOR %d => ,jug_actual+1); fprintf(t%x\t*\n", tids[jug_actual]); fprintf(f,"*****************************************\n\n"); } else { fprintf(f,"JUGADOR %d eliminado\n\n",jug_actual+1); jug_eliminado[jug_actual]=1; jug_eliminados++; /* Al eliminar la jugador comprobamos que quedan ms de dos jugadores particando para continuar con el juego, si no fuese as el juego termina y se busca el jugador que queda, ya que este ser el ganador */

20

Ampliacin de Sistemas Operativos

Quin es quin?

if( n_jugadores-1 == jug_eliminados ) { respuesta = 1; /* Ponemos respuesta a 1 para indicar al jugador que le juego ha acabado */ terminado = 1; /* Buscamos al ganador*/ i=-1; do{ i++; }while(jug_eliminado[i]==1); fprintf(f,"Han sido eliminados todos los jugadores menos uno\n"); fprintf(f,"\n*****************************************\n"); fprintf(f,"*\tGANADOR JUGADOR %d => t%x\t*\n",i+1,tids[i]); fprintf(f,"*****************************************\n\n"); } } } else { /* Obtenemos la respuesta a la pregunta formulada */ respuesta = obtener_respuesta(n_pregunta,personajes,n_personaje); fprintf(f,"Jugador %d => %s\n",jug_actual+1,preguntas[n_pregunta]); fprintf(f,"Ordenador => %s\n\n",respuesta ? "S" : "NO"); } /* Enviamos la respuesta al jugador. Si hizo una pregunta, si le enva un 1 significa que la respuesta es S y si enva un 0 es lo contrario. Si dijo un personaje se le manda si el juego ha terminado 1, o no 0 */ pvm_initsend(PvmDataDefault); pvm_pkint(&respuesta,1,1); pvm_send(tids[jug_actual],3); /* Buscamos el siguiente jugador en el orden, que siga participando */ do{ jug_actual=(jug_actual+1)%n_jugadores; }while(jug_eliminado[jug_actual]==1); } fprintf(f,"****** FIN JUEGO ******"); fclose(f); printf("\nLa partida ha sido almacenada en el fichero \"salida.txt\"\n\n"); free(tids); free(jug_eliminado); pvm_lvgroup( "juego" ); pvm_exit(); exit(0); }

21

Ampliacin de Sistemas Operativos


/* FUNCIN - obtener_respuesta

Quin es quin?

DESCRIPCIN - Funcin que a partir del nmero de la pregunta que recibe, devuelve la respuesta a dicha pregunta consultando el personaje elegido. Devolver 0 si la respuesta es "NO" o 1 si la respuesta es "S" PARMETROS - int n_pregunta, personaje *personajes, int n_personaje VALOR DEVUELTO - int (0 1) */ int obtener_respuesta(int n_pregunta,personaje *personajes,int n_personaje) { switch (n_pregunta) { case 0: return personajes[n_personaje].sexo==HOMBRE; case 1: return personajes[n_personaje].sexo==MUJER; case 2: return personajes[n_personaje].color_pelo==RUBIO; case 3: return personajes[n_personaje].color_pelo==MORENO; case 4: return personajes[n_personaje].color_pelo==PELIRROJO; case 5: return personajes[n_personaje].color_pelo==CASTANO; case 6: return personajes[n_personaje].color_pelo==CANOSO; case 7: return personajes[n_personaje].ojos==AZULES; case 8: return personajes[n_personaje].ojos==VERDES; case 9: return personajes[n_personaje].ojos==MARRONES; case 10: return personajes[n_personaje].ojos==NEGROS; case 11: return personajes[n_personaje].pecas==SI; case 12: return personajes[n_personaje].gafas==SI; case 13: return personajes[n_personaje].long_pelo==CORTO; case 14: return personajes[n_personaje].long_pelo==LARGO; case 15: return personajes[n_personaje].pendientes==SI; case 16: return personajes[n_personaje].barba==SI; } }

22

Ampliacin de Sistemas Operativos


/* FUNCIN - crear_personajes

Quin es quin?

DESCRIPCIN - Funcin que rellena el vector de estructuras que la funcin recibe, esta informacin representa los diferentes personajes que intervienen en el juego PARMETROS - personaje personajes[NPERS] VALOR DEVUELTO - Nada */ void crear_personajes(personaje personajes[NPERS]) { strcpy(personajes[0].nombre,"Mara"); personajes[0].sexo=MUJER; personajes[0].color_pelo=RUBIO; personajes[0].ojos=AZULES; personajes[0].pecas=SI; personajes[0].gafas=SI; personajes[0].long_pelo=LARGO; personajes[0].pendientes=SI; personajes[0].barba=NO; strcpy(personajes[1].nombre,"Rosa"); personajes[1].sexo=MUJER; personajes[1].color_pelo=RUBIO; personajes[1].ojos=VERDES; personajes[1].pecas=NO; personajes[1].gafas=NO; personajes[1].long_pelo=LARGO; personajes[1].pendientes=NO; personajes[1].barba=NO; strcpy(personajes[2].nombre,"Antonia"); personajes[2].sexo=MUJER; personajes[2].color_pelo=RUBIO; personajes[2].ojos=MARRONES; personajes[2].pecas=NO; personajes[2].gafas=NO; personajes[2].long_pelo=LARGO; personajes[2].pendientes=SI; personajes[2].barba=NO; strcpy(personajes[3].nombre,"Margarita"); personajes[3].sexo=MUJER; personajes[3].color_pelo=MORENO; personajes[3].ojos=NEGROS; personajes[3].pecas=NO; personajes[3].gafas=SI; personajes[3].long_pelo=LARGO; personajes[3].pendientes=NO; personajes[3].barba=NO; strcpy(personajes[4].nombre,"Violeta"); personajes[4].sexo=MUJER; personajes[4].color_pelo=MORENO; personajes[4].ojos=VERDES; personajes[4].pecas=SI; personajes[4].gafas=NO; personajes[4].long_pelo=LARGO; personajes[4].pendientes=SI; personajes[4].barba=NO; strcpy(personajes[5].nombre,"Eva"); personajes[5].sexo=MUJER; personajes[5].color_pelo=MORENO; personajes[5].ojos=MARRONES;

23

Ampliacin de Sistemas Operativos


personajes[5].pecas=NO; personajes[5].gafas=SI; personajes[5].long_pelo=LARGO; personajes[5].pendientes=SI; personajes[5].barba=NO; strcpy(personajes[6].nombre,"Marta"); personajes[6].sexo=MUJER; personajes[6].color_pelo=PELIRROJO; personajes[6].ojos=NEGROS; personajes[6].pecas=NO; personajes[6].gafas=NO; personajes[6].long_pelo=LARGO; personajes[6].pendientes=NO; personajes[6].barba=NO; strcpy(personajes[7].nombre,"ngela"); personajes[7].sexo=MUJER; personajes[7].color_pelo=CASTANO; personajes[7].ojos=MARRONES; personajes[7].pecas=SI; personajes[7].gafas=SI; personajes[7].long_pelo=LARGO; personajes[7].pendientes=SI; personajes[7].barba=NO; strcpy(personajes[8].nombre,"Luisa"); personajes[8].sexo=MUJER; personajes[8].color_pelo=CASTANO; personajes[8].ojos=MARRONES; personajes[8].pecas=NO; personajes[8].gafas=NO; personajes[8].long_pelo=LARGO; personajes[8].pendientes=SI; personajes[8].barba=NO; strcpy(personajes[9].nombre,"Alicia"); personajes[9].sexo=MUJER; personajes[9].color_pelo=CASTANO; personajes[9].ojos=NEGROS; personajes[9].pecas=NO; personajes[9].gafas=NO; personajes[9].long_pelo=LARGO; personajes[9].pendientes=NO; personajes[9].barba=NO; strcpy(personajes[10].nombre,"Vicenta"); personajes[10].sexo=MUJER; personajes[10].color_pelo=CANOSO; personajes[10].ojos=MARRONES; personajes[10].pecas=SI; personajes[10].gafas=NO; personajes[10].long_pelo=LARGO; personajes[10].pendientes=SI; personajes[10].barba=NO; strcpy(personajes[11].nombre,"Beatriz"); personajes[11].sexo=MUJER; personajes[11].color_pelo=RUBIO; personajes[11].ojos=MARRONES; personajes[11].pecas=NO; personajes[11].gafas=NO; personajes[11].long_pelo=CORTO; personajes[11].pendientes=SI; personajes[11].barba=NO; strcpy(personajes[12].nombre,"Ana");

Quin es quin?

24

Ampliacin de Sistemas Operativos


personajes[12].sexo=MUJER; personajes[12].color_pelo=MORENO; personajes[12].ojos=AZULES; personajes[12].pecas=NO; personajes[12].gafas=SI; personajes[12].long_pelo=CORTO; personajes[12].pendientes=SI; personajes[12].barba=NO; strcpy(personajes[13].nombre,"Inmaculada"); personajes[13].sexo=MUJER; personajes[13].color_pelo=PELIRROJO; personajes[13].ojos=MARRONES; personajes[13].pecas=NO; personajes[13].gafas=SI; personajes[13].long_pelo=CORTO; personajes[13].pendientes=NO; personajes[13].barba=NO; strcpy(personajes[14].nombre,"Teresa"); personajes[14].sexo=MUJER; personajes[14].color_pelo=CASTANO; personajes[14].ojos=NEGROS; personajes[14].pecas=NO; personajes[14].gafas=NO; personajes[14].long_pelo=CORTO; personajes[14].pendientes=SI; personajes[14].barba=NO; strcpy(personajes[15].nombre,"Esther"); personajes[15].sexo=MUJER; personajes[15].color_pelo=CANOSO; personajes[15].ojos=VERDES; personajes[15].pecas=SI; personajes[15].gafas=NO; personajes[15].long_pelo=CORTO; personajes[15].pendientes=NO; personajes[15].barba=NO; strcpy(personajes[16].nombre,"Pedro"); personajes[16].sexo=HOMBRE; personajes[16].color_pelo=RUBIO; personajes[16].ojos=MARRONES; personajes[16].pecas=NO; personajes[16].gafas=SI; personajes[16].long_pelo=LARGO; personajes[16].pendientes=NO; personajes[16].barba=SI; strcpy(personajes[17].nombre,"Emilio"); personajes[17].sexo=HOMBRE; personajes[17].color_pelo=MORENO; personajes[17].ojos=AZULES; personajes[17].pecas=NO; personajes[17].gafas=NO; personajes[17].long_pelo=LARGO; personajes[17].pendientes=NO; personajes[17].barba=NO; strcpy(personajes[18].nombre,"Javier"); personajes[18].sexo=HOMBRE; personajes[18].color_pelo=MORENO; personajes[18].ojos=NEGROS; personajes[18].pecas=SI; personajes[18].gafas=SI; personajes[18].long_pelo=LARGO; personajes[18].pendientes=NO;

Quin es quin?

25

Ampliacin de Sistemas Operativos


personajes[18].barba=NO; strcpy(personajes[19].nombre,"Rafael"); personajes[19].sexo=HOMBRE; personajes[19].color_pelo=PELIRROJO; personajes[19].ojos=VERDES; personajes[19].pecas=SI; personajes[19].gafas=NO; personajes[19].long_pelo=LARGO; personajes[19].pendientes=NO; personajes[19].barba=SI; strcpy(personajes[20].nombre,"Jorge"); personajes[20].sexo=HOMBRE; personajes[20].color_pelo=CASTANO; personajes[20].ojos=AZULES; personajes[20].pecas=NO; personajes[20].gafas=NO; personajes[20].long_pelo=LARGO; personajes[20].pendientes=NO; personajes[20].barba=SI; strcpy(personajes[21].nombre,"Miguel"); personajes[21].sexo=HOMBRE; personajes[21].color_pelo=CANOSO; personajes[21].ojos=NEGROS; personajes[21].pecas=NO; personajes[21].gafas=SI; personajes[21].long_pelo=LARGO; personajes[21].pendientes=NO; personajes[21].barba=NO; strcpy(personajes[22].nombre,"Francisco"); personajes[22].sexo=HOMBRE; personajes[22].color_pelo=RUBIO; personajes[22].ojos=NEGROS; personajes[22].pecas=NO; personajes[22].gafas=NO; personajes[22].long_pelo=CORTO; personajes[22].pendientes=NO; personajes[22].barba=NO; strcpy(personajes[23].nombre,"Enrique"); personajes[23].sexo=HOMBRE; personajes[23].color_pelo=RUBIO; personajes[23].ojos=VERDES; personajes[23].pecas=NO; personajes[23].gafas=SI; personajes[23].long_pelo=CORTO; personajes[23].pendientes=NO; personajes[23].barba=NO; strcpy(personajes[24].nombre,"Antonio"); personajes[24].sexo=HOMBRE; personajes[24].color_pelo=MORENO; personajes[24].ojos=NEGROS; personajes[24].pecas=NO; personajes[24].gafas=NO; personajes[24].long_pelo=CORTO; personajes[24].pendientes=NO; personajes[24].barba=SI; strcpy(personajes[25].nombre,"Jos"); personajes[25].sexo=HOMBRE; personajes[25].color_pelo=MORENO; personajes[25].ojos=VERDES; personajes[25].pecas=SI;

Quin es quin?

26

Ampliacin de Sistemas Operativos


personajes[25].gafas=NO; personajes[25].long_pelo=CORTO; personajes[25].pendientes=NO; personajes[25].barba=NO; strcpy(personajes[26].nombre,"Roberto"); personajes[26].sexo=HOMBRE; personajes[26].color_pelo=MORENO; personajes[26].ojos=MARRONES; personajes[26].pecas=NO; personajes[26].gafas=NO; personajes[26].long_pelo=CORTO; personajes[26].pendientes=NO; personajes[26].barba=NO; strcpy(personajes[27].nombre,"Fernando"); personajes[27].sexo=HOMBRE; personajes[27].color_pelo=PELIRROJO; personajes[27].ojos=AZULES; personajes[27].pecas=SI; personajes[27].gafas=SI; personajes[27].long_pelo=CORTO; personajes[27].pendientes=NO; personajes[27].barba=SI; strcpy(personajes[28].nombre,"Alberto"); personajes[28].sexo=HOMBRE; personajes[28].color_pelo=CASTANO; personajes[28].ojos=MARRONES; personajes[28].pecas=NO; personajes[28].gafas=NO; personajes[28].long_pelo=CORTO; personajes[28].pendientes=NO; personajes[28].barba=NO; strcpy(personajes[29].nombre,"Csar"); personajes[29].sexo=HOMBRE; personajes[29].color_pelo=CASTANO; personajes[29].ojos=VERDES; personajes[29].pecas=SI; personajes[29].gafas=NO; personajes[29].long_pelo=CORTO; personajes[29].pendientes=NO; personajes[29].barba=NO; strcpy(personajes[30].nombre,"Daniel"); personajes[30].sexo=HOMBRE; personajes[30].color_pelo=CANOSO; personajes[30].ojos=AZULES; personajes[30].pecas=NO; personajes[30].gafas=NO; personajes[30].long_pelo=CORTO; personajes[30].pendientes=NO; personajes[30].barba=SI; strcpy(personajes[31].nombre,"Lucas"); personajes[31].sexo=HOMBRE; personajes[31].color_pelo=CANOSO; personajes[31].ojos=MARRONES; personajes[31].pecas=NO; personajes[31].gafas=SI; personajes[31].long_pelo=CORTO; personajes[31].pendientes=NO; personajes[31].barba=NO; }

Quin es quin?

27

Ampliacin de Sistemas Operativos


/* FUNCIN - crear_preguntas

Quin es quin?

DESCRIPCIN - Funcin que rellena el vector de cadenas que la funcin recibe, esta informacin representa las diferentes preguntas que los jugadores pueden formular a lo largo del juego PARMETROS - personaje personajes[NPERS] VALOR DEVUELTO - Nada */ void crear_preguntas(char preguntas[NPREG][50]) { strcpy(preguntas[0],"Es hombre?"); strcpy(preguntas[1],"Tu personaje es mujer?"); strcpy(preguntas[2],"Tiene el pelo rubio?"); strcpy(preguntas[3],"Es moreno?"); strcpy(preguntas[4],"Tu personaje, Es pelirrojo?"); strcpy(preguntas[5],"El color de pelo es castao?"); strcpy(preguntas[6],"Tiene el pelo canoso?"); strcpy(preguntas[7],"Tiene los ojos azules?"); strcpy(preguntas[8],"El color de los ojos es verde?"); strcpy(preguntas[9],"Los ojos de tu personaje son marrones?"); strcpy(preguntas[10], "El color de ojos de tu personaje es negro?"); strcpy(preguntas[11],"Tiene pecas?"); strcpy(preguntas[12],"Lleva gafas?"); strcpy(preguntas[13],"Tu personaje tiene el pelo corto?"); strcpy(preguntas[14],"Tiene el pelo largo?"); strcpy(preguntas[15],"Lleva pendientes?"); strcpy(preguntas[16],"Tiene, tu personaje, barba?"); }

28

Ampliacin de Sistemas Operativos Fichero jugador.c


#include "trabajo.h"

Quin es quin?

int eliminar_personajes(int n_pregunta, int tabla_pers[NPERS],personaje *personajes,int respuesta); int eliminar_preguntas(int tabla_pers[NPERS], personaje personajes[NPERS], int tabla_preg[NPREG], int pers_posibles); int probabilidad_arriesgarse(int pers_posibles); int pregunta_aleatoria(int preg_eliminadas, int tabla_preg[NPREG]); int personaje_aleatorio(int pers_posibles, int tabla_pers[NPERS]); /* FUNCIN - main DESCRIPCIN - Funcin principal del jugador. Intenta adivinar el persanaje secreto. Para ello espera su turno, pregunta por una caracterstica o por un personaje, recibe la respuesta y la procesa, realizando las operaciones de acuerdo con esa respuesta. PARMETROS - int argc, char *argv[] VALOR DEVUELTO - Nada */ main(int argc, char *argv[]) { personaje personajes[NPERS]; char preguntas[NPREG][50]; int ptid;

/* los personajes que forman parte del juego */ /* las preguntas de las que consta el juego */ /* TID del proceso padre */

int tabla_pers[NPERS], tabla_preg[NPREG]; /* tablas donde se indican si un personaje o una pregunta, respectivamete, est eliminado o no */ int id_grupo; int i; int n_pregunta; int respuesta; int jug_inicial; int n_jugadores; int jug_izquierda, jug_derecha; int pers_posibles=NPERS; /* la posicin del jugador dentro del grupo */ /* variale auxiliar */ /* nmero de la pregunta que formula */ /* respuesta que recibe, S o NO */ /* la posicin del jugador dentro del grupo del jugador que comienza a jugar */ /* nmero de jugadores que participan */ /* TID del personaje que est situado a la derecha y a la izquierda en el anillo que se forma */ /* nmero de personajes que no han sido eliminados y por lo tanto pueden ser el personaje secreto. Inicialmente contiene el valor de NPERS */ /* nmero del persoanje que el jugador cree que puede ser el elegido por la mquina */ /* variable para indica si el juego ha acabado o no */ /* nmero de preguntas eliminadas. Inicialmente contiene el valor 0 */ /* variable que indica si el jugador est eliminado o no*/

int per_creido; int terminado; int preg_eliminadas= 0 int eliminado=0;

29

Ampliacin de Sistemas Operativos


n_jugadores=atoi(argv[argc-1]);

Quin es quin?
/* Obtenemos el nmero de jugadores que nos enva el motor del juego. Esta valor ser el ltimo argumento que pasa, por lo tanto estar almacenado en argv[argc-1], ya que argc es el nmero de elementos pasados y los vectores comienzan en 0 */

ptid = pvm_parent();

/* Obtenemos el TID del padre */ /* Adjuntamos al jugador al grupo. La posicin dentro del grupo ser entre 1 y n_jugadores, ya que el nmero 0 del grupo es el motor del juego*/

id_grupo= pvm_joingroup( juego" );

pvm_barrier( "juego", n_jugadores+1 ); /* Sincronizamos a todos los elementos del grupo, para que la comunicacin entre el motor y los jugadores sea correcta */ /* Recibimos del padre (motor del juego) y desempaquetamos los personajes y las preguntas del juego y el jugador que comenzar el juego*/ pvm_recv(ptid,1); for(i=0;i<NPERS;i++) { pvm_upkstr(personajes[i].nombre); pvm_upkint(&personajes[i].sexo,1,1); pvm_upkint(&personajes[i].color_pelo,1,1); pvm_upkint(&personajes[i].ojos,1,1); pvm_upkint(&personajes[i].pecas,1,1); pvm_upkint(&personajes[i].gafas,1,1); pvm_upkint(&personajes[i].long_pelo,1,1); pvm_upkint(&personajes[i].pendientes,1,1); pvm_upkint(&personajes[i].barba,1,1); tabla_pers[i]=0; /* Inicializamos todos los personajes como no eliminados */ } for(i=0;i<NPREG;i++) { pvm_upkstr(preguntas[i]); /* Probar pvm_psend */ tabla_preg[i]=0; /* Inicializamos todas las preguntas como no eliminadas */ } pvm_upkint(&jug_inicial,1,1); /* Determina los vecinos en el anillo. El anillo esta formado slo por los jugadores. Por lo tanto el vecino izquierdo del 1 es el n_jugadores y el de la derecha del n_jugadores es el 1 (ya que el 0 es le motor del juego y no forma parte del anillo) */ jug_izquierda = pvm_gettid("juego", id_grupo == 1 ? n_jugadores : id_grupo-1); jug_derecha = pvm_gettid("juego", id_grupo%n_jugadores + 1); /* Le damos el turno al jugador que ha sido elegido. El resto esperan hasta que les toque su turno, que les ser enviado por su vecino izquierdo del anillo, que es el jugador que les precede en el turno. Cuando se pasa el turno se enva una informacin "terminado", esta informacin nos indicar si el juego ha acabado o no (1 0 respectivamente) */ if( id_grupo == jug_inicial ) terminado=0; /*Inicializa "terminado" a 0 */ else { pvm_recv( jug_izquierda, 4 ); /* Espera su turno */ pvm_upkint(&terminado,1,1); /* Recibe si el juego ha acabado o no */ } srand ((unsigned int)time(NULL)+id_grupo);

30

Ampliacin de Sistemas Operativos

Quin es quin?

while(terminado == 0) { if( eliminado == 1 ) { /* Como est eliminado lo nico que hace es pasar el turno al siguinte */ pvm_initsend( PvmDataDefault ); pvm_pkint(&terminado,1,1); pvm_send( jug_derecha, 4); pvm_recv( jug_izquierda, 4); pvm_upkint(&terminado,1,1); } else { /* Si el jugador no est eliminado, puede pasar a preguntar. Si slo le queda un personaje como posible preguntar por l, adems tiene una probabilidad de arriesgarse an no estando seguro de quin es, esta probabilidad aumenta cuanto menos personajes le quede como posibles. Sino hace una pregunta sobre una caracterstica */ if( pers_posibles == 1 || rand()%100 < probabilidad_arriesgarse(pers_posibles)) { /* Elegimos un personaje aleatoriamente entre los que quedan */ per_creido = personaje_aleatorio(pers_posibles,tabla_pers); per_creido = -(per_creido+1); /* Encriptamos para que el motor del juego sepa que no es una pregunta */ /* Enviamos el personaje credo al motor */ pvm_initsend( PvmDataDefault ); pvm_pkint(&per_creido,1,1); pvm_send(ptid,2); /* Recibimos la respuesta del motor. En este caso este valor nos indicar si el juego ha acabado o no */ pvm_recv(ptid,3); pvm_upkint(&respuesta,1,1); if(respuesta) terminado=1; else eliminado=1; } else { /* Elegimos una pregunta aleatoriamente entre las que quedan */ n_pregunta=pregunta_aleatoria(preg_eliminadas,tabla_preg); /* Enviamos esa pregunta al motor del juego */ pvm_initsend( PvmDataDefault ); pvm_pkint(&n_pregunta,1,1); pvm_send( ptid, 2); /* Recibimos la respuesta del motor */ pvm_recv( ptid, 3 ); pvm_upkint(&respuesta,1,1); /* Elimina los personajes y las preguntas usando la informacin obtenida en este turno */ pers_posibles -= eliminar_personajes(n_pregunta,tabla_pers,personajes,respuesta); preg_eliminadas = eliminar_preguntas(tabla_pers, personajes, tabla_preg, pers_posibles); /* Si el juego no ha acabado es porque se ha equivocado y por lo tanto se elimina al jugador */ /* Si la respuesta es S entonces el juego ha acabado*/ /* Vuelve esperar su turno */

31

Ampliacin de Sistemas Operativos

Quin es quin?

/*Enviamos el turno al siguinete jugador */ pvm_initsend( PvmDataDefault ); pvm_pkint(&terminado,1,1); pvm_send( jug_derecha, 4); /* Esperamos ha recibir el turno */ pvm_recv( jug_izquierda, 4); pvm_upkint(&terminado,1,1); } } } /* Informamos al jugador de la derecha que el juego ya ha acabado, ya que si ha concluido el bucle significa que "terminado" es igual a 1 */ pvm_initsend( PvmDataDefault ); pvm_pkint(&terminado,1,1); pvm_send( jug_derecha, 4 ); /* El jugador finaliza dejando el grupo y saliendo de pvm */ pvm_lvgroup( "juego" ); pvm_exit(); exit(0); }

/* FUNCIN - probabilidad_arriesgase DESCRIPCIN - Funcin que representa una funcin de probabilidad en tanto por ciento. El parmetro de la funcin es la cantidad de personajes que no han sido eliminados, y por lo tanto pueden ser el personaje secreto, y la probabilidad es el valor que se devuelve. La probabilidad mnima es 1% (0.01), que es cuando el nmero de personajes que Quedan es menor o igual al NPERS y mayor que 16; y la mayor probabilidad es 20% (0.2), que es cuando slo quedan dos personajes posibles PARMETROS - int x VALOR DEVUELTO - int */ int probabilidad_arriesgarse(int pers_posibles) { if( pers_posibles <= NPERS && pers_posibles > 16 ) return 1; if( pers_posibles <= 16 && pers_posibles > 8 ) return 2; if( pers_posibles <= 8 && pers_posibles > 4 ) return 4; if( pers_posibles <= 4 && pers_posibles > 2 ) return 10; if( pers_posibles == 2 ) return 20; }

32

Ampliacin de Sistemas Operativos

Quin es quin?

/* FUNCIN - pregunta_aleatoria DESCRIPCIN - Funcin que se encarga de de elegir una pregunta de forma aleatoria entre los preguntas que no han sido eliminadas. Devuelve el nmero de la pregunta elegida PARMETROS - int preg_eliminadas, int tabla_preg[NPREG] VALOR DEVUELTO - int */ int pregunta_aleatoria(int preg_eliminadas, int tabla_preg[NPREG]) { int i, n_pregunta; i = rand()%(NPREG-preg_eliminadas); /* Generamos un nmero aleatorio par escoger entre las preguntas restantes*/

/* Buscamos la pregunta elegida buscando la i-sima pregunta no formulada */ n_pregunta=-1; do{ n_pregunta++; if(tabla_preg[n_pregunta]==0) i--; }while( i != -1 ); return n_pregunta; }

/* FUNCIN - personaje_aleatorio DESCRIPCIN - Funcin que se encarga de de elegir un personaje aleatoriamente entre los personajes que no han sido eliminados. Devuelve el nmero de ese personaje elegido PARMETROS - int pers_posibles, int tabla_pers[NPERS] VALOR DEVUELTO - int */ int personaje_aleatorio(int pers_posibles, int tabla_pers[NPERS]) { int i, n_personaje; i = rand()%(pers_posibles); /* Generamos un nmero aleatorio para escoger entre los personajes restantes*/

/* Buscamos el personaje elegido buscando el i-simo personaje no eliminado */ n_personaje=-1; do{ n_personaje++; if(tabla_pers[n_personaje]==0) i--; }while( i != -1 ); return n_personaje; }

33

Ampliacin de Sistemas Operativos


/* FUNCIN - eliminar_personajes

Quin es quin?

DESCRIPCIN - Funcin que se encarga de eliminar aquellos personajes que no pueden ser el personaje secreto, a partir de la respuesta que se ha dado a la pregunta formulada (ambos parmetros se pasan a la funcin). Se devuelve el nmero de personajes que se han eliminado para cada pregunta PARMETROS - int n_pregunta, int tabla_pers[NPERS],personaje personajes[NPERS],int respuesta VALOR DEVUELTO - int */ int eliminar_personajes(int n_pregunta, int tabla_pers[NPERS],personaje personajes[NPERS],int respuesta) { int i,pers_eliminados=0; /* Dependiendo de la pregunta tendremos que comprobar una caractrstica u otra de los personajes. Hacemos un recorrido por todos los personajes no eliminados y aquellos que no cumplan la condicin que se desprende de la respuesta a la pregunta formulada (que es la que cumple el personaje secreto), sern eliminados */ switch (n_pregunta) { case 0: for(i=0;i<NPERS;i++) if(tabla_pers[i]==0) if( (personajes[i].sexo==HOMBRE) != respuesta ) { tabla_pers[i]=1; pers_eliminados++; } break; case 1: for(i=0;i<NPERS;i++) if(tabla_pers[i]==0) if( (personajes[i].sexo==MUJER) != respuesta ) { tabla_pers[i]=1; pers_eliminados++; } break; case 2: for(i=0;i<NPERS;i++) if(tabla_pers[i]==0) if( (personajes[i].color_pelo==RUBIO) != respuesta ) { tabla_pers[i]=1; pers_eliminados++; } break; case 3: for(i=0;i<NPERS;i++) if(tabla_pers[i]==0) if( (personajes[i].color_pelo==MORENO) != respuesta ) { tabla_pers[i]=1; pers_eliminados++; } break;

34

Ampliacin de Sistemas Operativos

Quin es quin?

case 4: for(i=0;i<NPERS;i++) if(tabla_pers[i]==0) if( (personajes[i].color_pelo==PELIRROJO) != respuesta ) { tabla_pers[i]=1; pers_eliminados++; } break; case 5: for(i=0;i<NPERS;i++) if(tabla_pers[i]==0) if( (personajes[i].color_pelo==CASTANO) != respuesta ) { tabla_pers[i]=1; pers_eliminados++; } break; case 6: for(i=0;i<NPERS;i++) if(tabla_pers[i]==0) if( (personajes[i].color_pelo==CANOSO) != respuesta ) { tabla_pers[i]=1; pers_eliminados++; } break; case 7: for(i=0;i<NPERS;i++) if(tabla_pers[i]==0) if( (personajes[i].ojos==AZULES) != respuesta ) { tabla_pers[i]=1; pers_eliminados++; } break; case 8: for(i=0;i<NPERS;i++) if(tabla_pers[i]==0) if( (personajes[i].ojos==VERDES) != respuesta ) { tabla_pers[i]=1; pers_eliminados++; } break; case 9: for(i=0;i<NPERS;i++) if(tabla_pers[i]==0) if( (personajes[i].ojos==MARRONES) != respuesta ) { tabla_pers[i]=1; pers_eliminados++; } break; case 10: for(i=0;i<NPERS;i++) if(tabla_pers[i]==0) if( (personajes[i].ojos==NEGROS) != respuesta ) { tabla_pers[i]=1; pers_eliminados++; } break;

35

Ampliacin de Sistemas Operativos

Quin es quin?

case 11: for(i=0;i<NPERS;i++) if(tabla_pers[i]==0) if( (personajes[i].pecas==SI) != respuesta ) { tabla_pers[i]=1; pers_eliminados++; } break; case 12: for(i=0;i<NPERS;i++) if(tabla_pers[i]==0) if( (personajes[i].gafas==SI) != respuesta ) { tabla_pers[i]=1; pers_eliminados++; } break; case 13: for(i=0;i<NPERS;i++) if(tabla_pers[i]==0) if( (personajes[i].long_pelo==CORTO) != respuesta ) { tabla_pers[i]=1; pers_eliminados++; } break; case 14: for(i=0;i<NPERS;i++) if(tabla_pers[i]==0) if( (personajes[i].long_pelo==LARGO) != respuesta ) { tabla_pers[i]=1; pers_eliminados++; } break; case 15: for(i=0;i<NPERS;i++) if(tabla_pers[i]==0) if( (personajes[i].pendientes==SI) != respuesta ) { tabla_pers[i]=1; pers_eliminados++; } break; case 16: for(i=0;i<NPERS;i++) if(tabla_pers[i]==0) if( (personajes[i].barba==SI) != respuesta ) { tabla_pers[i]=1; pers_eliminados++; } } return pers_eliminados; }

36

Ampliacin de Sistemas Operativos


/* FUNCIN - eliminar_preguntas

Quin es quin?

DESCRIPCIN - Funcin que se encarga de eliminar aquellas preguntas que ya no hagan falta hacer para averiguar el perspnaje secreto, ya sea porque ya han sido formuladas o debido a que no hace falta plantearlas con la infomacin que se tiene a partir de los personajes no eliminados. Las preguntas eliminadas se sealan con un 1 en el vector tabla_preg. Devuelve el nmero total de preguntas eliminadas PARMETROS - int tabla_pers[NPERS], personaje personajes[NPERS], int tabla_preg[NPREG], int pers_posibles VALOR DEVUELTO - int */ int eliminar_preguntas(int tabla_pers[NPERS], personaje personajes[NPERS], int tabla_preg[NPREG], int pers_posibles) { int i; int preg_eliminadas=0; /* variables auxiliares para contar el nmero de personajes no eliminados que poseen la caracterstica que representa cada una */ int sexo=0; /* Nmero de mujeres que quedan*/ int pecas=0; /* Nmero de personajes que queda con pecas */ int gafas=0; /* Nmero de personajes que queda con gafas */ int long_pelo=0; /* Nmero de personajes que queda con pelo largo */ int barba=0; /* Nmero de personajes que queda con barba */ int pendientes=0; /* Nmero de personajes que queda con pendientes */ int rubio=0,moreno=0,pelirrojo=0,castano=0,canoso=0; /* Nmero de personajes que quedan con los diferentes colores de pelo */ int azules=0,verdes=0,marrones=0,negros=0; /* Nmero de personajes que quedan con los diferentes colores de ojos */

/* Obtenemos los valores de las variables auxiliares */ for(i=0;i<NPERS;i++) if(tabla_pers[i]==0) { sexo+=personajes[i].sexo; rubio+=personajes[i].color_pelo==RUBIO?1:0; moreno+=personajes[i].color_pelo==MORENO?1:0; pelirrojo+=personajes[i].color_pelo==PELIRROJO?1:0; castano+=personajes[i].color_pelo==CASTANO?1:0; canoso+=personajes[i].color_pelo==CANOSO?1:0; azules+=personajes[i].ojos==AZULES?1:0; verdes+=personajes[i].ojos==VERDES?1:0; marrones+=personajes[i].ojos==MARRONES?1:0; negros+=personajes[i].ojos==NEGROS?1:0; pecas+=personajes[i].pecas; gafas+=personajes[i].gafas; long_pelo+=personajes[i].long_pelo; barba+=personajes[i].barba; pendientes+=personajes[i].pendientes; } /* Si no hay mujeres o el nmero de mujeres es igual al nmero de personajes que quedan, las preguntas sobre el sexo del personaje no tienen sentido y se eliminan */ if( sexo == 0 || sexo == pers_posibles) { tabla_preg[0]=1; tabla_preg[1]=1; preg_eliminadas+=2; }

37

Ampliacin de Sistemas Operativos

Quin es quin?

if( rubio == pers_posibles || moreno == pers_posibles || pelirrojo == pers_posibles || castano == pers_posibles || canoso == pers_posibles) { /* Si todos los personajes tienen el mismo color de pelo, se eliminan todas las preguntas relacionadas con el color del pelo */ tabla_preg[2]=1; tabla_preg[3]=1; tabla_preg[4]=1; tabla_preg[5]=1; tabla_preg[6]=1; preg_eliminadas+=5; } else { /* Si todos los personajes no tienen el mismo color de pelo, pero alguno de los colores de pelo no aparecen en ningn personje, se eliminan todas las preguntas relacionadas con esos colores de pelo */ if(rubio == 0) { tabla_preg[2]=1; preg_eliminadas++; } if(moreno == 0) { tabla_preg[3]=1; preg_eliminadas++; } if(pelirrojo == 0) { tabla_preg[4]=1; preg_eliminadas++; } if(castano == 0) { tabla_preg[5]=1; preg_eliminadas++; } if(canoso == 0) { tabla_preg[6]=1; preg_eliminadas++; } } if( azules == pers_posibles || verdes == pers_posibles || marrones == pers_posibles || negros == pers_posibles) { /* Si todos los personajes tienen el mismo color de ojos, se eliminan todas las preguntas relacionadas con el color de ojos */ tabla_preg[7]=1; tabla_preg[8]=1; tabla_preg[9]=1; tabla_preg[10]=1; preg_eliminadas+=4; } else { /* Si todos los personajes no tienen el mismo color de ojos, pero alguno de los colores de ojos no aparecen en ningn personje, se eliminan todas las preguntas relacionadas con esos colores de ojos */ if(azules == 0) { tabla_preg[7]=1; preg_eliminadas++; }

38

Ampliacin de Sistemas Operativos


if(verdes == 0) { tabla_preg[8]=1; preg_eliminadas++; } if(marrones == 0) { tabla_preg[9]=1; preg_eliminadas++; } if(negros == 0) { tabla_preg[10]=1; preg_eliminadas++; } }

Quin es quin?

/* Si no hay personajes con pecas o el nmero de personajes con pecas es igual al nmero de personajes que quedan, la pregunta relativa a las pecas no tiene sentido y se elimina */ if( pecas == 0 || pecas == pers_posibles) { tabla_preg[11]=1; preg_eliminadas++; } /* Si no hay personajes con gafas o el nmero de personajes con gafas es igual al nmero de personajes que quedan, la pregunta sobre las gafass no tiene sentido y se elimina */ if( gafas == 0 || gafas == pers_posibles) { tabla_preg[12]=1; preg_eliminadas++; } /* Si no hay personajes con el pelo largo o el nmero de personajes con el pelo largo es igual al nmero de personajes que quedan, las preguntas relativas a la longitud del pelo no tiene sentido y se eliminan */ if( long_pelo == 0 || long_pelo == pers_posibles) { tabla_preg[14]=1; tabla_preg[15]=1; preg_eliminadas+=2; } /* Si no hay personajes con barba o el nmero de personajes con barba es igual al nmero de personajes que quedan, la pregunta sobre la barba no tiene sentido y se elimina */ if( barba == 0 || barba == pers_posibles) { tabla_preg[15]=1; preg_eliminadas++; } /* Si no hay personajes con pendientes o el nmero de personajes con pendientes es igual al nmero de personajes que quedan, la pregunta relativa a los pendientes no tiene sentido y se elimina */ if( pendientes == 0 || pendientes == pers_posibles) { tabla_preg[16]=1; preg_eliminadas++; } return preg_eliminadas; }

39

Ampliacin de Sistemas Operativos Fichero Makefile

Quin es quin?

ARCHCFLAGS = -DSYSVBFUNC -DSYSVSTR -DNOGETDTBLSIZ -DSYSVSIGNAL DNOWAIT3 -DNOUNIXDOM ARCHLIB = -lnsl -lsocket -lthread PVM_ARCH = SUNMP # # Custom makefile for PVM programs. # # Set PVM_ROOT to the path where PVM includes and libraries are installed. # Set PVM_ARCH to your architecture type (SUN4, HP9K, RS6K, SGI, etc.) # Set ARCHLIB to any special libs needed on PVM_ARCH (-lrpc, -lsocket, etc.) # otherwise leave ARCHLIB blank # SDIR = .. #BDIR = $(HOME)/pvm3/bin BDIR = $(SDIR)/../bin XDIR = $(BDIR)/$(PVM_ARCH) CC = OPTIONS CFLAGS LIBS = GLIBS = F77 = FFLAGS = FLIBS = LFLAGS = gcc = -O = $(OPTIONS) -I$(PVM_ROOT)/include $(ARCHCFLAGS) -lpvm3 $(ARCHLIB) -lgpvm3 f77 -g -lfpvm3 -L$(PVM_ROOT)/lib/$(PVM_ARCH)

default: juego jugador clean: rm -f *.o juego jugador $(XDIR): - mkdir $(BDIR) - mkdir $(XDIR) juego: $(SDIR)/juego.c $(XDIR) $(CC) $(CFLAGS) -o juego $(SDIR)/juego.c $(LFLAGS) $(GLIBS) $(LIBS) mv juego $(XDIR) jugador: $(SDIR)/jugador.c $(XDIR) $(CC) $(CFLAGS) -o jugador $(SDIR)/jugador.c $(LFLAGS) $(GLIBS) $(LIBS) mv jugador $(XDIR)

40

Ampliacin de Sistemas Operativos

Quin es quin?

ANEXO B: Exclusin mutua. Algoritmo de anillos de fichas.


Con frecuencia, los sistemas con varios procesos se programan ms fcilmente mediante las secciones crticas. Cuando un proceso debe leer o actualizar ciertas estructuras de datos compartidas, primero entra a una regin crtica para lograr la exclusin mutua y garantizar que ningn otro proceso utilice las estructuras de datos al mismo tiempo. En tos sistemas con un procesador, las regiones crticas se protegen mediante semforos, monitores y construcciones similares. A continuacin pasamos a describir un mtodo para lograr la exclusin mutua en un sistema distribuido: el algoritmo de anillo de fichas. Supongamos que tenemos una red basada en bus sin un orden inherente en los procesos. Bajo software, se construye un anillo lgico y a cada proceso se le asigna una posicin en el anillo. Las posiciones del anillo se pueden asignar segn el orden numrico de las direcciones de la red o mediante algn otro medio. No importa cmo sea el orden. Lo importante es que cada proceso sepa quin es el siguiente en la fila despus de l. Al iniciar el anillo, se le da al proceso k (una ficha, la cual circula por todo el anillo. Se transfiere del proceso k al proceso k+1 (mdulo al tamao del anillo) en mensajes puntuales. Cuando un proceso obtiene la ficha de su vecino, verifica si intenta entrar en la regin crtica. En ese caso, el proceso entra a la regin, hace todo el trabajo necesario y sale de la regin. Despus de salir, pasa la ficha a lo largo de! anillo. No se permite entrar a una segunda regin crtica con la misma ficha. Si un proceso recibe la ficha de su vecino y no est interesado en entrar a una regin crtica, slo la vuelve a pasar. En consecuencia, cuando ninguno de los procesos desea entrar a una regin crtica, la ficha slo circula a gran velocidad en el anillo. Es evidente que el anillo es correcto. En un instante dado, slo uno de los procesos tiene la ficha, por lo que slo un proceso puede estar en una regin crtica. Puesto que las fichas circulan entre los procesos en orden bien definido, no puede existir la inanicin. Una vez que un proceso decide entrar a una regin crtica, lo peor que puede ocurrir es que deba esperar a que los dems procesos entren y salgan de ella. Como es usual, tambin este algoritmo tiene problemas. Si la ficha llega a perderse, debe ser regenerada. De hecho es difcil detectar su prdida, puesto que la cantidad de tiempo entre las apariciones sucesivas de la ficha en la red no est acotada. El hecho de que la ficha no se haya observado durante una hora no significa su prdida; tal vez alguien la est utilizando.

41

Ampliacin de Sistemas Operativos

Quin es quin?

El algoritmo tambin tiene problemas si falla un proceso, pero la recuperacin es ms sencilla que en los dems casos. Si pedimos un reconocimiento a cada proceso que reciba la ficha, entonces se detectar un proceso muerto si su vecino intenta darle la ficha y fracasa en el intento. En ese momento, el proceso muerto se puede eliminar del grupo y el poseedor de la ficha puede enviar sta por encima de la cabeza del proceso muerto al siguiente miembro, y as, sucesivamente, en caso necesario. Por supuesto, esto requiere que todos mantengan la configuracin actual de anillo.

42

Ampliacin de Sistemas Operativos

Quin es quin?

ANEXO C: Primitivas de PVM utilizadas


A continuacin se comentar el uso de las primitivas de PVM en este programa.

Principales rutinas de control de procesos pvm_mytid. Se usa para que el proceso juego obtenga su TID. Llamada: mytid = pvm_ mytid(); pvm_exit. La llaman los procesos para indicar al pvmd local que el proceso est saliendo de PVM. Esta rutina no mata al proceso, el cual puede seguir realizando tareas como cualquier otro proceso UNIX. Llamada: mytid = pvm_ exit(); pvm_spawn. Lo usamos para crear los jugadores. Creamos n_jugadores copias del fichero ejecutable jugador sobre la mquina virtual, argv es un puntero al array de argumentos a jugador, con el final del array especificado por NULL. En el argumento flag ponemos un 0 para que PVM elija donde expandir los jugadores; en el argumento where es NULL, indicando que expanda las tareas por defecto; y TIDs indica la direccin de memoria donde se almacenarn los TIDs de las tareas creadas. Recogemos el nmero de tareas creada en info, para ver si se han creado todos los jugadores pedidos. Llamada: info = pvm_spawn("jugador", argv, 0, NULL, n_jugadores, tids) pvm_kill. Lo llama el proceso jugador para eliminar a los procesos jugadores, cuando se produce un error durante el juego. Le llamamos tantas veces como jugadores haya, y le pasamos el TID de cada uno. Llamada: pvm_kill(tids[i]);

Rutinas de informacin pvm_parent. Lo usan los jugadores para obtener el TID del juego. Llamada: ptid = pvm_parent();

43

Ampliacin de Sistemas Operativos

Quin es quin?

pvm_perror. Lo usan los procesos para obtener informacin de los errores que se producen.

Ejemplo de llamada: pvm_perror("ERROR: El grupo est corrupto\n");

Rutinas de informacin pvm_initsend. Antes de enviar informacin limpiamos el buffer de envo. Como parmetro usamos la opcin PvmDataDefault. Llamada: pvm_initsend(PvmDataDefault);

pvm_pkint, pvm_upkint. La usan los procesos para empaquetar o desempaquetar los enteros que se pasan unos a otros. Le pasamos como argumentos, el puntero al entero que deseamos enviar o en el que deseamos recibir dicho entero; y el en resto ponemos los parmetros por defecto. Ejemplo de llamada: pvm_pkint(&personajes[i].sexo,1,1);

pvm_pkstr, pvm_upkstr. La usan los procesos para empaquetar y desempaquetar las cadenas que se desean enviar o recibir. Le pasamos como argumento el puntero a la cadena que deseamos enviar o en la que deseamos recibir dicha cadena. Ejemplo de llamada: pvm_pkstr(preguntas[i]);

pvm_sent. La usan para enviar los mensajes. En cada caso ponemos como primer parmetro el TID del proceso al que vamos a enviar el mensaje. El segundo parmetro es la etiqueta de paso de mensajes.

Ejemplo de llamada: pvm_send( jug_derecha, 4); pvm_recv. Los procesos la usan para ponerse a la espera de la llegada de un mensaje. Se produce bloqueo para sincronizarse con el envo. Como primer parmetro le pasamos el TID del proceso del que espera el envo, y como segundo la etiqueta de paso de mensajes, que deber ser igual que la del envo. Ejemplo de llamada: pvm_recv(tids[jug_actual],2);

44

Ampliacin de Sistemas Operativos Grupos dinmicos de procesos

Quin es quin?

pvm_joingroup. Unimos a los jugadores y al juego al grupo juegos. En la llamada del juego comprobamos que es el primer elemento del grupo. En la de los jugadores, recoge su identificador dentro del grupo. Llamadas: id_grupo= pvm_joingroup( "jugadores" ); if( pvm_joingroup("jugadores") != 0 )

pvm_barrier. Bloqueamos todos los procesos del grupo para que se sincronicen. Le pasamos el nombre del grupo y el nmero de elementos del grupo.

Llamada: pvm_barrier( "jugadores", n_jugadores+1 );

pvm_bcast. Lo usa el juego para enviar informacin sobre el juego a todos los elementos del grupo excepto l; es decir, a todos los jugadores. Como primer parmetro le pasamos el nombre del grupo, y como segundo la etiqueta de paso de mensajes. Llamada: pvm_bcast("jugadores",1);

pvm_gettid. La usan los procesos para obtener el TID del elemento del grupo identificado por el identificador de grupo pasado como segundo parmetro, el primeo es el nombre del grupo. Ejemplo de llamada: tids[i] = pvm_gettid("jugadores", i+1);

pvm_lvgroup. La llaman los procesos para dejar el grupo. Pasan como parmetro el nombre del grupo. Llamada: pvm_lvgroup(juego);

45

Ampliacin de Sistemas Operativos

Quin es quin?

ANEXO D: Ejecucin y Salida del programa


D.1. Ejecucin
Una vez que obtenemos el ejecutable del juego juego, para ellos usamos la orden aimk juego jugador, pasamos a ejecutar el juego, esto se puede hacer de dos formas: Llamando al ejecutable sin ningn parmetro. En este caso, se pedir por pantalla el nmero de jugadores. Comando => juego. Llamando al ejecutable pasndole como nico parmetro el nmero de jugadores. Este nmero tendr que estar entre 2 y el nmero mximo de jugadores definido (si no se modifica es 10).jugadores. Comando => juego 3. Una vez ejecutado y terminado, tendremos el desarrollo0de la partida en el fichero salida.txt.

D.1. Salida
Salidas de algunas pruebas realizadas al programa (fichero salida.txt): Prueba 1 Nmero de jugadores que participan en el juego: 8 Jugador 1: t40036 Jugador 2: t40037 Jugador 3: t80029 Jugador 4: t8002b Jugador 5: t8002a Jugador 6: tc002e Jugador 7: tc0030 Jugador 8: tc002f La mquina ha elegido a Esther como personaje a adivinar Empieza el jugador 1 Jugador 1 => Tiene el pelo canoso? Ordenador => S 46

Ampliacin de Sistemas Operativos Jugador 2 => Tu personaje tiene el pelo corto? Ordenador => S Jugador 3 => Lleva gafas? Ordenador => NO Jugador 4 => Es moreno? Ordenador => NO Jugador 5 => Tu personaje es mujer? Ordenador => S Jugador 6 => Tiene el pelo canoso? Ordenador => S Jugador 7 => El color de pelo es castao? Ordenador => NO Jugador 8 => Lleva gafas? Ordenador => NO Jugador 1 => Los ojos de tu personaje son marrones? Ordenador => NO Jugador 2 => Tu personaje tiene el pelo corto? Ordenador => S Jugador 3 => Tiene el pelo largo? Ordenador => NO Jugador 4 => Tu personaje, Es pelirrojo? Ordenador => NO Jugador 5 => Tiene el pelo largo? Ordenador => NO Jugador 6 => Tu personaje es mujer? Ordenador => S Jugador 7 => Es hombre? Ordenador => NO Jugador 8 => Tiene el pelo canoso? Ordenador => S Jugador 1 => Tu personaje es mujer? Ordenador => S Jugador 2 => Tu personaje es mujer? Ordenador => S

Quin es quin?

47

Ampliacin de Sistemas Operativos Jugador 3 => Tiene el pelo rubio? Ordenador => NO Jugador 4 => Es hombre? Ordenador => NO Jugador 5 => Lleva gafas? Ordenador => NO Jugador 6 => Es Vicenta? Ordenador => NO JUGADOR 6 eliminado Jugador 7 => El color de ojos de tu personaje es negro? Ordenador => NO Jugador 8 => El color de los ojos es verde? Ordenador => S Jugador 1 => Es Esther? Ordenador => S ***************************************** * GANADOR JUGADOR 1 => t40036 * ***************************************** ****** FIN JUEGO ******

Quin es quin?

Prueba 2 Nmero de jugadores que participan en el juego: 5 Jugador 1: t40046 Jugador 2: t40047 Jugador 3: t80034 Jugador 4: t80035 Jugador 5: tc0039 La mquina ha elegido a Jorge como personaje a adivinar Empieza el jugador 4 Jugador 4 => Tiene el pelo canoso? Ordenador => NO Jugador 5 => Tiene el pelo rubio? Ordenador => NO 48

Ampliacin de Sistemas Operativos Jugador 1 => Los ojos de tu personaje son marrones? Ordenador => NO Jugador 2 => Tiene, tu personaje, barba? Ordenador => S Jugador 3 => Lleva pendientes? Ordenador => NO Jugador 4 => Tu personaje es mujer? Ordenador => NO Jugador 5 => Es hombre? Ordenador => S Jugador 1 => Tiene el pelo largo? Ordenador => S Jugador 2 => El color de ojos de tu personaje es negro? Ordenador => NO Jugador 3 => El color de ojos de tu personaje es negro? Ordenador => NO Jugador 4 => Tiene el pelo largo? Ordenador => S Jugador 5 => El color de ojos de tu personaje es negro? Ordenador => NO Jugador 1 => Tiene pecas? Ordenador => NO Jugador 2 => El color de los ojos es verde? Ordenador => NO Jugador 3 => Tiene pecas? Ordenador => NO Jugador 4 => Tu personaje tiene el pelo corto? Ordenador => NO Jugador 5 => El color de pelo es castao? Ordenador => S Jugador 1 => Tu personaje, Es pelirrojo? Ordenador => NO Jugador 2 => Tiene el pelo canoso? Ordenador => NO

Quin es quin?

49

Ampliacin de Sistemas Operativos Jugador 3 => Tu personaje es mujer? Ordenador => NO Jugador 4 => Lleva gafas? Ordenador => NO Jugador 5 => El color de los ojos es verde? Ordenador => NO Jugador 1 => Es hombre? Ordenador => S Jugador 2 => Es Jorge? Ordenador => S ***************************************** * GANADOR JUGADOR 2 => t40047 * ***************************************** ****** FIN JUEGO ******

Quin es quin?

Prueba 3 Nmero de jugadores que participan en el juego: 3 Jugador 1: t40041 Jugador 2: t80031 Jugador 3: tc0036 La mquina ha elegido a Alberto como personaje a adivinar Empieza el jugador 2 Jugador 2 => Tiene los ojos azules? Ordenador => NO Jugador 3 => Tiene el pelo rubio? Ordenador => NO Jugador 1 => Tiene, tu personaje, barba? Ordenador => NO Jugador 2 => Tiene el pelo rubio? Ordenador => NO Jugador 3 => Tu personaje es mujer? Ordenador => NO

50

Ampliacin de Sistemas Operativos Jugador 1 => Tiene pecas? Ordenador => NO Jugador 2 => Los ojos de tu personaje son marrones? Ordenador => S Jugador 3 => Tiene pecas? Ordenador => NO Jugador 1 => Tu personaje tiene el pelo corto? Ordenador => S Jugador 2 => Es moreno? Ordenador => NO Jugador 3 => Lleva gafas? Ordenador => NO Jugador 1 => Los ojos de tu personaje son marrones? Ordenador => S Jugador 2 => Tiene el pelo canoso? Ordenador => NO Jugador 3 => Lleva pendientes? Ordenador => NO Jugador 1 => Es moreno? Ordenador => NO Jugador 2 => Tiene, tu personaje, barba? Ordenador => NO Jugador 3 => El color de ojos de tu personaje es negro? Ordenador => NO Jugador 1 => Lleva gafas? Ordenador => NO Jugador 2 => Tiene, tu personaje, barba? Ordenador => NO Jugador 3 => El color de pelo es castao? Ordenador => S Jugador 1 => El color de pelo es castao? Ordenador => S Jugador 2 => Es ngela? Ordenador => NO JUGADOR 2 eliminado

Quin es quin?

51

Ampliacin de Sistemas Operativos Jugador 3 => Los ojos de tu personaje son marrones? Ordenador => S Jugador 1 => Es Alberto? Ordenador => S ***************************************** * GANADOR JUGADOR 1 => t40041 * ***************************************** ****** FIN JUEGO ******

Quin es quin?

Prueba 4 Nmero de jugadores que participan en el juego: 2 Jugador 1: t80033 Jugador 2: tc0038 La mquina ha elegido a Violeta como personaje a adivinar Empieza el jugador 2 Jugador 2 => Los ojos de tu personaje son marrones? Ordenador => NO Jugador 1 => Tu personaje, Es pelirrojo? Ordenador => NO Jugador 2 => El color de los ojos es verde? Ordenador => S Jugador 1 => El color de ojos de tu personaje es negro? Ordenador => NO Jugador 2 => Es Esther? Ordenador => NO JUGADOR 2 eliminado Han sido eliminados todos los jugadores menos uno ***************************************** * GANADOR JUGADOR 1 => t80033 * ***************************************** ****** FIN JUEGO ******

52

Das könnte Ihnen auch gefallen