Probablemente esta es la primera vez que tengan que acometer la construcción de una aplicación concurrente. El desarrollo de esta clase de sistemas exige ser más cuidadoso y metódico. En este apartado le proponemos unas recomendaciones que pueden ayudarles a completar el trabajo con un mínimo de complicaciones.
Esto es, requerimientos y funcionamiento general. Si tiene dudas pregunte al profesor que tiene asignado para la tutorización y corrección de su práctica.
Antes de pasar al diseño de los programas del servidor y cliente céntrese en los requerimientos de sincronización y comunicación que se plantean y estudie, mediante trazas, las distintas situaciones de comunicación que se pueden dar en un sistema con el proceso servidor y varios clientes. Una vez estudiado el problema planteado, diseñe una solución mediante las técnicas explicadas en clase. Algunos casos de estudio vistos en el aula son muy similares al problema de este trabajo.
Una vez diseñada la solución al problema de comunicación, pase a la implementación en el entorno UNIX. Para ello es prerrequisito conocer el funcionamiento general de los mecanismos IPC de UNIX. Una vez dominado este aspecto, pase a la implementación, en este estado del diseño, y como consecuencia de su conocimiento del funcionamiento de las herramientas IPC, es posible que se plantee un rediseño de los mecanismos de comunicación debido a que se dará cuenta que los mecanismos IPC son más potentes y flexibles que los mecanismos vistos en la teoría, el llevar a cabo esta optimización es opcional.
Cada vez que el servidor atiende una petición, debe crear un
proceso hijo, esperar a que el nuevo proceso se ejecute y tras ello recoger
información sobre cómo terminó el hijo. Estas actividades
se resuelven con llamadas al sistema de UNIX, como son
fork()
, wait()
y
exit()
. Para dominar estas herramientas, le recomendamos
que implemente un programa sencillo que genere un proceso hijo, espere por su
finalización y cuando ésta ocurra obtenga el código de
finalización del proceso generado. Este programa le podrá servir
de esqueleto para una parte del programa servidor.
La ejecución de la función fork()
produce la creación de un nuevo proceso que es imagen del proceso que la
invocó originalmente (proceso padre). En nuestro caso el proceso hijo
ejecutará un programa distinto al padre. Por tanto, habrá de
reemplazar su código y sus datos por los del programa que se desea
ejecutar. La familia de funciones exec...
del UNIX se
encargan de ello.
Basándose en el programa sencillo del apartado anterior, intente que el
proceso hijo lance un programa, especificado con una cadena de caracteres. Una
vez que lo anterior funcione, englóbelo en una función que reciba
como parámetro un char*
con la orden para ejecutar.
Como el proceso servidor deberá ejecutarse en forma de demonio, será necesario conocer los pasos necesarios para dejar un proceso en segundo plano y desvinculado de una terminal.
Observe que si ha seguido al pie de la letra las recomendaciones anteriores tendrá mucho camino recorrido. Dispone de una biblioteca de funciones que resuelven los problemas básicos de la práctica.
Realice un diseño general de los programas del servidor y del cliente. Exponga sus resultados al profesor tutor. Si éste le da el visto bueno, ya puede codificar la práctica y terminar su trabajo.