Descarga la aplicación para disfrutar aún más
Esta es una vista previa del archivo. Inicie sesión para ver el archivo original
Practicas/SSOO_g_ii_p3_concurrencia_(threads)_enunciado_13-14.pdf Área de Arquitectura y Tecnología de Computadores Universidad Carlos III de Madrid SISTEMAS OPERATIVOS Práctica 3. Programación de una biblioteca de gestión de stock concurrente (Multithread) Grado de Ingeniería en Informática Curso 2013/2014 Departamento de Informática Grado en Ingeniería Informática Sistemas Operativos (2013-2014) Práctica 3 - Concurrencia 1 Índice 1. Enunciado de la Práctica ................................................................................................................. 2 1.1. Descripción de la Práctica........................................................................................................ 2 1.1.1. Interfaz de la base de datos ............................................................................................ 3 1.1.2. Interfaz secuencial ........................................................................................................... 5 1.1.3. Interfaz concurrente ........................................................................................................ 8 1.2. Código Fuente de Apoyo ....................................................................................................... 11 2. Entrega .......................................................................................................................................... 13 2.1. Puntuación de la práctica ...................................................................................................... 13 2.2. Pruebas a realizar .................................................................................................................. 13 2.3. Plazo de entrega .................................................................................................................... 14 2.4. Ficheros a entregar ................................................................................................................ 14 3. Normas .......................................................................................................................................... 16 4. Anexo (man function). ................................................................................................................... 17 5. Bibliografía ..................................................................................................................................... 17 Departamento de Informática Grado en Ingeniería Informática Sistemas Operativos (2013-2014) Práctica 3 - Concurrencia 2 1. Enunciado de la Práctica Esta práctica permite al alumno familiarizarse con los servicios para la gestión de procesos ligeros (hilos o threads) que proporciona POSIX. Se pretende que el alumno comprenda la importancia de sincronizar los hilos cuando trabajan de forma concurrente. Para la gestión de hilos, se utilizarán las llamadas al sistema de POSIX relacionadas, como pthread_create y pthread_join. Para la sincronización de hilos, se utilizarán mutex y variables condicionales mediante llamadas como pthread_mutex_init, pthread_mutex_lock, pthread_mutex_unlock, pthread_cond_init, pthread_cond_wait, pthread_cond_signal, pthread_cond_destroy. El alumno deber diseñar y codificar, en lenguaje C y sobre sistema operativo UNIX/Linux, una librería de acceso a la base de datos de un almacén de modo que las operaciones sean consistentes incluso en caso de que sucedan de forma concurrente. 1.1. Descripción de la Práctica Se pretende codificar una biblioteca que permita la concurrencia de la biblioteca db_warehouse. La biblioteca db_warehouse proporcionada permite gestionar los productos de un almacén así como el stock actual de cada uno de ellos, pero no soporta que varios clientes puedan acceder a la vez. Se desea codificar una nueva interfaz que se sitúe entre el usuario y la base de datos, que dé soporte a esta concurrencia. La biblioteca a codificar, denominada concurrent, tiene que cumplir los siguientes requisitos: Debe permitir realizar operaciones concurrentes sobre la base de datos sobre distintos elementos de la misma. Debe mantener la coherencia de los elementos de la base de datos (tanto en la creación, como en la eliminación o la actualización de los datos). Se debe respetar la interfaz propuesta en el enunciado, sin posibilidad de realizar ningún cambio en la misma. Es decir: La biblioteca a desarrollar debe soportar el uso de múltiples procesos ligeros “por encima” de la interfaz. No se pueden realizar operaciones de creación o borrado de un producto si se está realizando cualquier otra operación sobre la base de datos. En cambio, se pueden realizar operaciones de actualización de distintos productos de forma concurrente. Departamento de Informática Grado en Ingeniería Informática Sistemas Operativos (2013-2014) Práctica 3 - Concurrencia 3 Existirá un máximo de operaciones de consultas concurrente sobre el total de la base de datos que vendrá marcado por la constante MAX_READERS que se encuentra en el fichero concurrent.h. 1.1.1. Interfaz de la base de datos La interfaz proporcionada para acceder a la base de datos se detalla a continuación. Esta interfaz ya está codificada y se proporciona junto al código fuente de la práctica pre- compilada, es decir, se podrá acceder al fichero de cabeceras, pero no al código. NOTA: Todos los parámetros pasados a las funciones tienen que tener algún valor. En el caso de que pase algún valor a NULL, la función devolverá siempre un valor de -1. La base de datos podrá administrar hasta 16 productos, es decir, se podrán crear o borrar productos tantas veces como se desee, pero sólo podrá haber un máximo de 16 productos activos. int db_warehouse_init() o Descripción: función que inicializa la base de datos. Usar solo una vez al inicio. o Valor de retorno: 0 → ok, -1 → error int db_warehouse_destroy() o Descripción: función que elimina los recursos utilizados de la base de datos. Usar solo una vez al finalizar. o Ámbito: afecta a la totalidad de la base de datos. o Valor de retorno: 0 → ok, -1 → error int db_warehouse_create_product (char *product_name) o Descripción: función que crea un nuevo producto en el primer registro disponible del almacén. No controla la existencia de otros productos con el mismo nombre. o Ámbito: afecta a la totalidad de la base de datos. o Entrada: nombre del producto. o Valor de retorno: 0 → ok, -1 → error que significa que no existen registros libres para la creación del producto (16 productos activas). int db_warehouse_get_num_products(int *num_products) Departamento de Informática Grado en Ingeniería Informática Sistemas Operativos (2013-2014) Práctica 3 - Concurrencia 4 o Descripción: función que devuelve el número de productos activos en el almacén. o Salida: número de productos activos en el almacén. o Valor de retorno: 0 → ok, -1 → error int db_warehouse_delete_product(char *product_name) o Descripción: función que elimina el primer producto que encuentre con el mismo nombre que el solicitado. o Ámbito: afecta a la totalidad de la base de datos. o Entrada: nombre del producto. o Valor de retorno: 0 → ok, -1 → error en caso de que no se encuentre ningún producto con el nombre solicitado. int db_warehouse_exists_product(char *product_name) o Descripción: función que indica si existe un producto. o Entrada: nombre del producto a buscar. o Valor de retorno: 1 → existe, 0 → No existe int db_warehouse_update_stock(char *product_name, int stock) o Descripción: función que actualiza el stock de un producto. o Ámbito: afecta al producto solicitado. o Entrada: nombre del producto y stock del producto. o Valor de retorno: 0 → ok, -1 → error en caso de que no se encuentre ningún producto con el nombre solicitado int db_warehouse_get_stock(char *product_name, int *stock) o Descripción: función que devuelve el stock de un producto. o Ámbito: afecta al producto solicitado. o Entrada: nombre del producto. o Salida: stock del producto. o Valor de retorno: 0 → ok, -1 → error en caso de que no se encuentre ningún producto con el nombre solicitado. Departamento de Informática Grado en Ingeniería Informática Sistemas Operativos (2013-2014) Práctica 3 - Concurrencia 5 int db_warehouse_set_internal_data(char *product_name, void *ptr, int size) o Descripción: función que permite asociar una serie de datos a un producto concreto. Se puede utilizar para guardar con el producto datos relacionados con la sincronización de procesos ligeros. o Ámbito: afecta al producto solicitado. o Entrada: nombre del producto, puntero a los datos y tamaño de los mismos. o Valor de retorno: 0 → ok, -1 → error en caso de que no se encuentre ningún producto con el nombre solicitado. int db_warehouse_get_internal_data(char *product_name, void **ptr, int *size) o Descripción: función que devuelve los datos internos asociados a un producto. o Ámbito: afecta l producto solicitado. o Entrada: nombre del producto. o Salida: puntero a los datos y tamaño de los mismos. o Valor de retorno: 0 → ok, -1 → error en caso de que no se encuentre ningún producto con el nombre solicitado. 1.1.2. Interfaz secuencial En este apartado se detalla la interfaz secuencial. Esta interfaz ya está codificada y se proporciona junto al código fuente de la práctica. El objetivo de esta interfaz es mostrar un ejemplo de codificación secuencial de la funcionalidad requerida, es decir, incluye todo el código que se debe implementar salvo los mecanismos de sincronización de hilos. Se debe respetar este código a la hora de implementar la versión concurrente. int sequential_init() o Descripción: función que inicializa los recursos utilizados en la biblioteca, así como la base de datos utilizada. Usar sólo una vez al inicio. o Valor de retorno: 0 → ok, -1 → error int sequential_destroy() o Descripción: función que elimina los recursos utilizados en la biblioteca, así como los utilizados en la base de datos. Usar sólo una vez al final del programa. o Valor de retorno: 0→ ok, -1→ error Departamento de Informática Grado en Ingeniería Informática Sistemas Operativos (2013-2014) Práctica 3 - Concurrencia 6 int sequential_create_product(char *product_name) o Descripción: función que crea un producto en la base de datos. En caso de encontrar otro producto con el mismo nombre, se considera que la creación se ha realizado con éxito. o Entrada: nombre del producto. o Valor de retorno: 0 → ok, -1→ error int sequential_get_num_products(int *num_products) o Descripción: función que consulta en la base de datos el número de productos activos en el almacén. o Salida: devuelve el número de productos activos en el almacén. o Valor de retorno: 0→ ok, -1 → error int sequential_delete_product(char *product_name) o Descripción: función que borra un producto de la base de datos. En caso de no encontrarse un producto con el mismo nombre, se considera que el borrado se ha realizado con éxito. o Entrada: nombre del producto. o Valor de retorno: 0 → ok, -1→ error int sequential_increment_stock(char *product_name, int stock, int *updated_stock) o Descripción: función que incrementa el stock de un producto y devuelve el stock actualizado. o Entrada: nombre del producto y el stock a incrementar. o Salida: devuelve el stock actualizado. o Valor de retorno: 0 → ok, -1 → error (producto no encontrado, etc.) int sequential_decrement_stock(char *product_name, int stock, int *updated_stock) o Descripción: función que decrementa el stock de un producto y devuelve el stock actualizado. o Entrada: nombre del producto y el stock a restar. o Salida: devuelve el stock actualizado. o Valor de retorno: 0→ ok, -1 → error (producto no encontrado, etc.) Departamento de Informática Grado en Ingeniería Informática Sistemas Operativos (2013-2014) Práctica 3 - Concurrencia 7 int sequential_get_stock(char *product_name, int *stock) o Descripción: función que devuelve el stock de un producto. o Entrada: nombre del producto. o Salida: devuelve el stock actualizado. o Valor de retorno: 0→ ok, -1 → error (producto no encontrado, etc.) Departamento de Informática Grado en Ingeniería Informática Sistemas Operativos (2013-2014) Práctica 3 - Concurrencia 8 1.1.3. Interfaz concurrente En este apartado se detalla la interfaz a codificar. Se debe respetar, codificando el contenido de sus funciones para permitir el acceso concurrente a la base de datos del almacén. int concurrent_init() o Descripción: función que inicializa los recursos utilizados en la biblioteca, así como la base de datos utilizada y los mecanismos de control de concurrencia. Usar solo una vez al inicio. No debe controlar ningún tipo de concurrencia. o Control de concurrencia: no debe controlar ningún tipo de concurrencia. o Valor de retorno: 0 → ok, -1 → error int concurrent_destroy() o Descripción: función que elimina los recursos utilizados en la biblioteca, así como los utilizados en la base de datos y los mecanismos de control de concurrencia. Usar solo una vez al final del programa. o Control de concurrencia: no debe controlar ningún tipo de concurrencia. o Valor de retorno: 0 → ok, -1 → error int concurrent_create_product(char *product_name) o Descripción: función que crea un producto en la base de datos utilizando concurrencia. En caso de encontrar otro producto con el mismo nombre, se considera que la creación se ha realizado con éxito. Debe mantener la coherencia de la BD. No permite realizar otras operaciones al mismo tiempo. o Control de concurrencia: no debe permitir que se realice ninguna otra operación sobre la base de datos al mismo tiempo. o Entrada: nombre del producto. o Valor de retorno: 0 → ok, -1 → error int concurrent_get_num_products(int *num_products) o Descripción: función que consulta en la base de datos el número de productos activos utilizando gestión de la concurrencia. Debe mantener la coherencia de la BD. o Control de concurrencia: solo debe permitir que se produzcan otras operaciones de consulta sobre la base de datos (hasta un máximo de MAX_READERS). Las operaciones permitidas serán obtener número de productos y cualquier operación sobre un producto concreto. o Salida: devuelve el número de productos existentes en el almacén. o Valor de retorno: 0 → ok, -1 → error Departamento de Informática Grado en Ingeniería Informática Sistemas Operativos (2013-2014) Práctica 3 - Concurrencia 9 int concurrent_delete_product(char *product_name) o Descripción: función que borra un producto de la base de datos utilizando control de concurrencia. En caso de no encontrarse un producto con el mismo nombre, se considera que el borrado se ha realizado con éxito. Debe mantener la coherencia de la BD. No permite realizar otras operaciones al mismo tiempo. o Control de concurrencia: no debe permitir que se realice ninguna otra operación sobre la base de datos al mismo tiempo. o Entrada: nombre del producto. o Valor de retorno: 0 → ok, -1 → error int concurrent_increment_stock(char *product_name, int stock, int *updated_stock) o Descripción: función que incrementa el stock de un producto y devuelve el stock actualizado. Debe permitir actualizar o leer otros productos en paralelo. o Control de concurrencia: no debe permitir que se realice ninguna otra operación sobre el producto afectado al mismo tiempo. Contará como una operación de consulta sobre la base de datos (hasta un máximo de MAX_READERS). o Entrada: nombre del producto y el stock a incrementar. o Salida: devuelve el stock actualizado. o Valor de retorno: 0 → ok, -1 → error (producto no encontrado, etc.) int concurrent_decrement_stock(char *product_name, int stock, int *updated_stock) o Descripción: función que decrementa el stock de un producto y devuelve el stock actualizado. Debe permitir actualizar o leer otros productos en paralelo. o Control de concurrencia: no debe permitir que se realice ninguna otra operación sobre el producto afectado al mismo tiempo. Contará como una operación de consulta sobre la base de datos (hasta un máximo de MAX_READERS). o Entrada: nombre del producto y el stock a restar. o Salida: devuelve el stock actualizado. o Valor de retorno: 0 → ok, -1 → error (producto no encontrado, etc.) int concurrent_get_stock(char *product_name, int *stock) o Descripción: función que devuelve el stock de un producto. Debe permitir actualizar o leer otros productos en paralelo. Departamento de Informática Grado en Ingeniería Informática Sistemas Operativos (2013-2014) Práctica 3 - Concurrencia 10 o Control de concurrencia: debe permitir que se realicen otras consultas simultáneas sobre el producto, pero ninguna otra operación de actualización sobre el producto afectado al mismo tiempo. Contará como una operación de consulta sobre la base de datos (hasta un máximo de MAX_READERS). o Entrada: nombre del producto. o Salida: devuelve el stock actualizado. o Valor de retorno: 0 → ok, -1 → error (producto no encontrado, etc.) Departamento de Informática Grado en Ingeniería Informática Sistemas Operativos (2013-2014) Práctica 3 - Concurrencia 11 1.2. Código Fuente de Apoyo Para facilitar la realización de esta práctica se dispone del fichero ssoo_p3_concurrency_2014.tar.gz que contiene código fuente de apoyo. Para extraer su contenido ejecutar lo siguiente: tar zxvf ssoo_p3_concurrency_2014.tar.gz Al extraer su contenido, se crea el directorio ssoo_p3_concurrency/, donde se debe desarrollar la práctica. Dentro de este directorio se habrán incluido los siguientes ficheros: ssoo_p3_concurrency/Makefile Fichero de compilación (para ejecutar "make", para borrar los ficheros "make clean"). ssoo_p3_concurrency/lib/ Directorio con las bibliotecas del sistema ssoo_p3_concurrency/lib/libdb_warehouse.a Biblioteca para el manejo de la base de datos compilada en las aulas de la asignatura. ssoo_p3_concurrency/lib/libdb_warehouse-64bits.a Biblioteca para el manejo de la base de datos compilada en una máquina de 64 bits. Si se quiere utilizar, renombrarla a libdb_warehouse.a sustituyendo a la anterior. ssoo_p3_ concurrency/include/ Directorio con los ficheros de cabeceras. ssoo_p3_concurrency/include/db_warehouse.h Fichero de cabeceras con las funciones de manejo de la base de datos del almacén. ssoo_p3_concurrency/include/sequential.h Fichero de cabeceras con las funciones de manejo secuencial de ejemplo. ssoo_p3_concurrency/include/concurrent.h Fichero de cabeceras con las funciones de manejo de la biblioteca concurrente. ssoo_p3_concurrency/sequential.c Fichero que contiene las funciones para la utilización de la librería del almacén de forma secuencial. Se trata de un código cuya funcionalidad es exactamente la misma que la requerida salvo por los mecanismos de sincronización ausentes. ssoo_p3_concurrency/concurrent.c Fichero que contiene las funciones para la utilización concurrente de la librería del almacén. Este es el ÚNICO FICHERO QUE SE DEBE MODIFICAR. SE DEBE RESPETAR Y UTILIZAR EL CÓDIGO YA EXISTENTE a la hora de codificar la librería concurrente. Departamento de Informática Grado en Ingeniería Informática Sistemas Operativos (2013-2014) Práctica 3 - Concurrencia 12 ssoo_p3_concurrency/sequential_example.c Fichero de ejemplo que utiliza las funciones descritas en la biblioteca secuencial. Es sólo un ejemplo de funcionamiento, las pruebas que se realicen al código entregado serán más complejas. ssoo_p3_concurrency/concurrent_example.c Fichero de ejemplo que utiliza las funciones descritas en la biblioteca concurrente. Es sólo un ejemplo de funcionamiento, las pruebas que se realicen al código entregado serán más complejas. Departamento de Informática Grado en Ingeniería Informática Sistemas Operativos (2013-2014) Práctica 3 - Concurrencia 13 2. Entrega 2.1. Puntuación de la práctica A continuación se indica un desglose de cómo será puntuada la práctica: 40% - Operaciones a nivel global de almacén: crear, borrar y obtener número de productos. (Control de concurrencia de actualización y consulta a nivel global). 40% - Operaciones a nivel de producto: Incrementar, decrementar y consultar el stock de los productos. (Control de concurrencia de actualización y consulta a nivel global y de producto). 20% - Memoria. 2.2. Pruebas a realizar El código entregado debe ser capaz de superar las siguientes pruebas, como mínimo: - Se deben poder lanzar operaciones de actualización de la base de datos del almacén de forma concurrente (crear y borrar productos) manteniendo las condiciones de concurrencia, es decir, que no se realicen dos escrituras a la vez. - Se deben poder lanzar operaciones de consulta de la base de datos del almacén de forma concurrente (obtener número de productos) manteniendo las condiciones de concurrencia, en este caso será posible que las lecturas se realicen de forma simultánea. - En caso de que haya operaciones de lectura y escritura lanzadas de forma simultánea, las operaciones de lectura deberán esperar por las operaciones de escritura que ya se encuentren en curso y viceversa. - En caso de que sean operaciones sobre productos, bien sean actualizaciones (incremento y decremento de stock) o consultas (obtener stock) debe respetar el mismo orden indicado anteriormente, en este caso, tan solo afectando al producto sobre la que se realicen las operaciones y no sobre el almacén completo, es decir, podrán ser modificados varios productos de forma simultánea, pero no un mismo producto por varios usuarios. - Se debe tener siempre en cuenta que el número de lectores concurrentes sobre la base de datos será siempre de MAX_READERS como máximo. Es decir, se podrán hacer hasta MAX_READERS consultas simultáneas a la base de datos, considerando una consulta de la base de datos como: obtener el número total de Departamento de Informática Grado en Ingeniería Informática Sistemas Operativos (2013-2014) Práctica 3 - Concurrencia 14 productos o cualquier operación (consulta o actualización de stock) sobre un producto concreto. 2.3. Plazo de entrega La fecha límite de entrega de la práctica se podrá consultar en AULA GLOBAL. La entrega de las prácticas ha de realizarse de forma electrónica. En AULA GLOBAL se habilitarán unos enlaces a través de los cuales podrá realizar la entrega de las prácticas. En concreto, se habilitará un entregador para el código de la práctica, y otro de tipo TURNITIN para la memoria de la práctica. 2.4. Ficheros a entregar Se debe entregar un archivo comprimido en formato zip con el nombre ssoo_p3_AAAAAAAAA_BBBBBBBBB.zip donde A…A y B…B son los NIAs de los integrantes del grupo. En caso de realizar la práctica en solitario, el formato será ssoo_p3_AAAAAAAAA.zip. El archivo zip se entregará en el entregador correspondiente al código de la práctica. El archivo debe contener: o concurrent.c o autores.txt El fichero autores.txt deberá contener el nombre y NIA de cada autor en líneas separadas, ejemplo: AUTOR1 NIA1 AUTOR2 NIA2 Para comprimir mediante línea de comandos, se puede utilizar el comando: zip ssoo_p2_AAAAAAAAA_BBBBBBBBB concurrent.c autores.txt La memoria se entregará en formato PDF en un fichero llamado ssoo_p3_AAAAAAAAA_BBBBBBBBB.pdf. Solo se corregirán y calificarán memorias en formato pdf. Tendrá que contener al menos los siguientes apartados: Descripción del código detallando las principales funciones implementadas. NO incluir código fuente de la práctica en este apartado. Cualquier código será automáticamente ignorado. Departamento de Informática Grado en Ingeniería Informática Sistemas Operativos (2013-2014) Práctica 3 - Concurrencia 15 Batería de pruebas utilizadas y resultados obtenidos. Se dará mayor puntuación a pruebas avanzadas, casos extremos, y en general a aquellas pruebas que garanticen el correcto funcionamiento de la práctica en todos los casos. Hay que tener en cuenta: o Que un programa compile correctamente y sin advertencias (warnings) no es garantía de que funcione correctamente. o Evite pruebas duplicadas que evalúan los mismos flujos de programa. La puntuación de este apartado no se mide en función del número de pruebas, sino del grado de cobertura de las mismas. Es mejor pocas pruebas que evalúan diferentes casos a muchas pruebas que evalúan siempre el mismo caso. Conclusiones, problemas encontrados, cómo se han solucionado, y opiniones personales. Se puntuará también los siguientes aspectos relativos a la presentación de la práctica: Debe contener portada, con los autores de la práctica y sus NIAs. Debe contener índice de contenidos. La memoria debe tener números de página en todas las páginas (menos la portada). El texto de la memoria debe estar justificado. El archivo pdf se entregará en el entregador correspondiente la memoria de la práctica (entregador TURNITIN). NOTA: La única versión registrada de su práctica es la última entregada. La valoración de esta es la única válida y definitiva. Departamento de Informática Grado en Ingeniería Informática Sistemas Operativos (2013-2014) Práctica 3 - Concurrencia 16 3. Normas 1) No se permitirá la utilización de llamadas como sleep, msleep o funciones cuyo objetivo sea similar a éstas. 2) Las prácticas que no compilen o que no se ajusten a la funcionalidad y requisitos planteados, obtendrán una calificación de 0. 3) El entorno de pruebas de cara a la evaluación de la práctica será guernika. Asegúrese de que si práctica funciona correctamente en guernika mediante ssh o bien en los laboratorios del departamento de informática. 4) Se prestará especial atención a detectar funcionalidades copiadas entre dos prácticas. En caso de encontrar implementaciones comunes en dos prácticas, ambas obtendrán una calificación de 0. 5) Los programas deben compilar sin warnings. De lo contrario, se penalizará la nota de la práctica. 6) Un programa no comentado, obtendrá una calificación de 0. 7) La entrega de la práctica se realizará a través de Aula Gloval, tal y como se detalla en el apartado Entrega de este documento. No se permite la entrega a través de correo electrónico sin autorización previa. 8) Se debe respetar en todo momento el formato de la entrada y salida que se indica en cada programa a implementar. 9) Se debe realizar un control de errores en cada uno de los programas. - Una práctica que no supere el corrector de formato recibirá una penalización en la nota. Los programas entregados que no sigan estas normas no se considerarán aprobados. Departamento de Informática Grado en Ingeniería Informática Sistemas Operativos (2013-2014) Práctica 3 - Concurrencia 17 4. Anexo (man function). man es el paginador del manual del sistema, es decir permite buscar información sobre un programa, una utilidad o una función. Véase el siguiente ejemplo: ‘man pthread_create’ o ‘man 3 pthread_create’ Las páginas usadas como argumentos al ejecutar man suelen ser normalmente nombres de programas, utilidades o funciones. Normalmente, la búsqueda se lleva a cabo en todas las secciones de manual disponibles según un orden predeterminado, y sólo se presenta la primera página encontrada, incluso si esa página se encuentra en varias secciones. Para salir de la página mostrada, basta con pulsar la tecla 'q'. Una página de manual tiene varias partes. Éstas están etiquetadas como NOMBRE, SINOPSIS, DESCRIPCIÓN, OPCIONES, FICHEROS, VÉASE TAMBIÉN, BUGS, y AUTOR. En la etiqueta de SINOPSIS se recogen las librerías (identificadas por la directiva #include) que se deben incluir en el programa en C del usuario para poder hacer uso de las funciones correspondientes. Las formas más comunes de usar man son las siguientes: man sección elemento: Presenta la página de elemento disponible en la sección del manual. man -a elemento: Presenta, secuencialmente, todas las páginas del elemento disponibles en el manual. Entre página y página se puede decidir saltar a la siguiente o salir del paginador completamente. man -k palabra-clave: Busca la palabra-clave entre las descripciones breves y las páginas de manual y presenta todas las que casen. 5. Bibliografía - El lenguaje de programación C: diseño e implementación de programas Félix García, Jesús Carretero, Javier Fernández y Alejandro Calderón. Prentice-Hall, 2002. - The UNIX System S.R. Bourne Addison-Wesley, 1983. - Advanced UNIX Programming M.J. Rochkind Prentice-Hall, 1985. - Sistemas Operativos: Una visión aplicada Jesús Carretero, Félix García, Pedro de Miguel y Fernando Pérez. McGraw-Hill, 2001. - Programming Utilities and Libraries SUN Microsystems, 1990. - Unix man pages (man function) Practicas/SSOO_g_ii_gestion_procesos_13-14.pdf Área de Arquitectura y Tecnología de Computadores Universidad Carlos III de Madrid SISTEMAS OPERATIVOS Práctica 2. Gestión de procesos Grado de Ingeniería en Informática Curso 2013/2014 1 Índice 1. Introducción .......................................................................................................................... 2 1.1. Descripción ................................................................................................................... 3 1.1.0. Ejercicio 0: núcleo de la minishell ........................................................................ 3 1.1.1. Ejercicio 1: ejecución de un comando simple ....................................................... 4 1.1.2. Ejercicio 2: ejecución de un comando simple con argumento .............................. 4 1.1.3. Ejercicio 3: ejecución de un comando simple con redirección de salida .............. 5 1.1.4. Ejercicio 4: ejecución de un comando simple con redirección de entrada ............ 6 1.1.5. Ejercicio 5: comandos con tuberías ....................................................................... 7 1.1.6. Ejercicio 6: comandos con tuberías, redirección de la salida ................................ 8 1.1.7. Ejercicio 7: tres comandos con tuberías, redirección de la salida y de error ......... 9 1.1.8. Ejercicio 8: tres comandos con tuberías, redirección de la salida y ejecución en segundo plano ..................................................................................................................... 10 1.1.9. Ejercicio 9: manejo de señales ............................................................................ 11 1.2. Código inicial .............................................................................................................. 12 1.3. Comprobador de formato ............................................................................................ 12 2. Entrega ................................................................................................................................ 13 2.1. Plazo de entrega y procedimiento ............................................................................... 13 2.2. Ficheros a entregar ...................................................................................................... 13 3. Normas ............................................................................................................................... 15 4. Bibliografía ......................................................................................................................... 16 2 1. Introducción El objetivo de esta práctica es mostrar al alumno una visión práctica de cómo se lleva a cabo la gestión de procesos, la comunicación entre ellos y con el sistema operativo. Existen llamadas al sistema que proporcionan las funciones necesarias para la creación, comunicación y finalización de los procesos. A lo largo de esta práctica, el alumno debe demostrar que es capaz de hacer un buen uso de este conjunto de llamadas dentro de su programa. Para llevar a cabo la verificación de conocimientos, el alumno debe desarrollar un programa que, dada la entrada introducida por teclado, ejecute un comando u otro. Los comandos que deben ejecutarse en función del parámetro introducido por teclado ya están predefinidos y el usuario podrá elegir cual desea ejecutar en cada momento. Una vez finalizada la ejecución de un comando, el programa volverá a solicitar al usuario otro comando para ejecutar. Esto será de así hasta que el usuario escriba la palabra “exit”. Los comandos que debe ofrecer el programa deben ser implementados empleando llamadas al sistema. Cada comando puede componerse de una o más tareas. Para ejecutar estas tareas el alumno debe crear los procesos que estime necesario y comunicarlos para obtener el resultado indicado. Para llevar a cabo esta funcionalidad, puede emplear las siguientes llamadas al sistema: Para crear nuevos procesos y ejecutar diferentes comandos, el alumno puede emplear fork y excepvp. Las tuberías (pipe, dup y close) serán utilizadas por el alumno para comunicar los distintos procesos creados entre sí. Si el usuario requiere de alguna redirección de entrada o salida serán tratadas con open, dup y close. El alumno usará wait y waitpid para que el proceso principal (main) espere hasta la finalización de los procesos creados antes de indicarle al usuario que puede ejecutar otro comando. Para manejar y capturar una señal determinada, el alumno usará signal. A continuación se procederá a la descripción de cada uno de los comandos que el alumno debe ejecutar y las llamadas al sistema necesarias en cada una de ellos. 3 1.1. Descripción La práctica ha sido diseñada para que el alumno la realice de forma incremental. En primer lugar el alumno debe realizar un ejercicio 0 y, una vez terminado, se pondrá con el uno, luego con el dos y así hasta finalizar todos los ejercicios planteados. Toda la práctica se realizará obre el archivo minishell.c. Este código al finalizar la práctica debe contener las funciones necesarias para ejecutar desde el núcleo o ejercicio 0 hasta el último comando. 1.1.0. Ejercicio 0: núcleo de la minishell El alumno debe empezar su minishell creando un bucle infinito. Por cada ejecución del bucle se deberá mostrar por pantalla el prompt de la minishell (“minishell> ”) y esperar a que el usuario introduzca una línea por teclado. Si la línea introducida por el usuario es “exit”, la minishell deberá finalizar su ejecución retornando un 0. Si por el contrario es cualquier otra cosa, el programa no realizará nada y esperará por otra línea. A continuación se muestra un ejemplo de ejecución del núcleo de la minishell: user@ubuntu:./minishell minishell>do-something minishell>do-other-thing minishell>exit user@ubuntu: Notas: Se pueden utilizar las funciones scanf (de stdio.h) y strcmp (de string.h) para leer y comparar la línea que introduzca el usuario. El programa debe imprimir el prompt (“minishell>”) El programa debe ser capaz de aceptar un número ilimitado de entradas. El programa retornará 0 si el usuario introduce “exit”. 4 1.1.1. Ejercicio 1: ejecución de un comando simple Si el usuario introduce por teclado “command1”, la minishell debe ejecutar el comando uptime. Este comando imprime por consola información sobre cuánto tiempo lleva la máquina encendida. minishell>command1 15:31:00 up 1 day, 22:31, 3 users, load average: 0.00, 0.01, 0.05 minishell> Notas: Use fork para crear un nuevo proceso. Use execvp en el código del proceso hijo para ejecutar el comando uptime. Use wait o waitpid en el padre para esperar hasta la finalización del comando. El programa debe retornar -1 si existe algún problema realizando cualquiera de las llamadas al sistema. 1.1.2. Ejercicio 2: ejecución de un comando simple con argumento Si el usuario introduce por teclado “command2”, la minishell debe ejecutar el comando uname –a. Este comando imprime por pantalla la información acerca de la distribución y versión del kernel en ejecución. minishell>command2 Linux ubuntu 3.2.0-57-generic #87-Ubuntu SMP Tue Nov 12 21:35:10 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux minishell> Notas: Use fork para crear un nuevo proceso Use execvp en el código del proceso hijo para ejecutar el comando uname -a Use wait o waitpid en el padre para esperar hasta la finalización del comando. El programa debe retornar -1 si existe algún problema realizando cualquiera de las llamadas al sistema. 5 1.1.3. Ejercicio 3: ejecución de un comando simple con redirección de salida Si el usuario introduce por teclado “command3”, la minishell debe ejecutar el comando cat /proc/cpuinfo > <output_file>. Este comando debe imprimir en el fichero indicado la información sobre la CPU. minishell>command3 output_file.txt minishell> -- The output from /proc/cpuinfo will have been saved to output_file.txt -- Notas: El usuario debe introducir el nombre del fichero de salida en la misma línea que el comando. Se puede invocar la función scanf dos veces: la primera obtendrá el nombre del comando y la segunda obtendrá el nombre del fichero. La salida del comando cat /proc/cpuinfo debe ser redirigida al fichero. Se deben emplear para ello las funciones open, dup y close. Use wait o waitpid en el padre para esperar hasta la finalización del comando. El proceso principal de la minishell realizará el fork de todos los procesos hijos. El programa debe retornar -1 si existe algún problema realizando cualquiera de las llamadas al sistema. 6 1.1.4. Ejercicio 4: ejecución de un comando simple con redirección de entrada Si el usuario introduce por teclado “command4”, la minishell debe ejecutar el comando grep “model name” < <input_file>. Este comando filtrará la información de la CPU mostrando sólo el modelo de procesador. En el ejemplo que se muestra a continuación, se ha introducido como fichero de entrada el generado con el ejercicio 3. minishell>command4 input_file.txt -- Outputted file from the previous exercise -- model name : Intel(R) Core(TM) i5 CPU 760 @ 2.80GHz model name : Intel(R) Core(TM) i5 CPU 760 @ 2.80GHz model name : Intel(R) Core(TM) i5 CPU 760 @ 2.80GHz model name : Intel(R) Core(TM) i5 CPU 760 @ 2.80GHz minishell> Notas: El usuario debe introducir el nombre del fichero de entrada en la misma línea que el comando. Se puede invocar la función scanf dos veces: la primera obtendrá el nombre del comando y la segunda obtendrá el nombre del fichero. Se debe redirigir la entrada del comando, para ello se deben emplear las funciones open, dup y close. Use wait o waitpid en el padre para esperar hasta la finalización del comando. El proceso principal de la minishell realizará el fork de todos los procesos hijos. El programa debe retornar -1 si existe algún problema realizando cualquiera de las llamadas al sistema. 7 1.1.5. Ejercicio 5: comandos con tuberías Si el usuario introduce por teclado “command5”, la minishell debe ejecutar el comando cat /proc/cpuinfo | grep “model name”. Este comando realizará lo mismo que el anterior pero sin utilizar un fichero de entrada. minishell>command5 model name : Intel(R) Core(TM) i5 CPU 760 @ 2.80GHz model name : Intel(R) Core(TM) i5 CPU 760 @ 2.80GHz model name : Intel(R) Core(TM) i5 CPU 760 @ 2.80GHz model name : Intel(R) Core(TM) i5 CPU 760 @ 2.80GHz minishell> Notas: Utilizar una tubería para redirigir la salida de la primera parte del comando a la entrada de la segunda parte del comando (pipe, dup y close). Utilizar wait o waitpid en el código del padre para esperar hasta que el comando finalice. El proceso principal de la minishell realizará el fork de todos los procesos hijos. El programa debe devolver -1 si hay algún problema en cualquiera de las llamadas al sistema. 8 1.1.6. Ejercicio 6: comandos con tuberías, redirección de la salida Si el usuario introduce por teclado “command6”, la minishell debe ejecutar el comando du –ha . | grep 4\.0K > <output_file>. La minishell debe solicitar al usuario el fichero de salida antes de ejecutar el comando. Este comando busca ficheros de 4KB o menos en el directorio actual (y sus subdirectorios). minishell>command6 output_file.txt minishell> -- The output from du –ha . | grep 4\.0K will have been saved to output_file.txt -- Utilizar una tubería para redirigir la salida de la primera parte del comando a la entrada de la segunda parte del comando (pipe, dup y close). El usuario debe introducir el nombre del fichero de salida en la misma línea que el comando. Se puede invocar la función scanf dos veces: la primera obtendrá el nombre del comando y la segunda obtendrá el nombre del fichero. La salida de la segunda parte del comando se redirigirá a dicho fichero. Se debe utilizar las funciones open, dup y close. Utilizar wait o waitpid en el código del padre para esperar hasta que el comando finalice. El proceso principal de la minishell realizará el fork de todos los procesos hijos. El programa debe devolver -1 si hay algún problema en cualquiera de las llamadas al sistema. 9 1.1.7. Ejercicio 7: tres comandos con tuberías, redirección de la salida y de error Si el usuario introduce por teclado “command7”, la minishell debe ejecutar el comando du –ha . | grep 4\.0K | cut –f2 > <output_file> &> <error_file>. La minishell debe solicitar al usuario dos nombres de fichero antes de ejecutar el comando. La primera vez solicitará el fichero de salida y la segunda vez el fichero de error. Este comando busca ficheros de 4KB o menos en el directorio actual (y sus subdirectorios). Solo se imprimirá el nombre del fichero. minishell>command7 output_file.txt error_file.txt minishell> -- The output from du –ha . | grep 4\.0K | cut –f2 will have been saved to output_file.txt -- -- The error from du –ha . | grep 4\.0K | cut –f2 will have been saved to error_file.txt -- Notas: Utilizar dos tuberías o La primera para redirigir la salida de la primera parte del comando a la entrada de la segunda parte del comando (pipe, dup y close). o La segunda para redirigir la salida de la segunda parte del comando a la entrada de la tercera parte del comando. El usuario debe introducir el nombre del fichero de salida y del fichero de error en la misma línea que el comando. Se puede invocar la función scanf tres veces: la primera obtendrá el nombre del comando, la segunda obtendrá el nombre del fichero de salida y la tercera obtendrá el nombre del fichero de error. La salida de la tercera parte del comando se redirigirá al fichero de salida. Se debe utilizar las funciones open, dup y close. La salida de de error de todas las partes del comando se redirigirán al fichero de error. Se debe utilizar las funciones open, dup y close. Utilizar wait o waitpid en el código del padre para esperar hasta que el comando finalice. El proceso principal de la minishell realizará el fork de todos los procesos hijos. El programa debe devolver -1 si hay algún problema en cualquiera de las llamadas al sistema. 10 1.1.8. Ejercicio 8: tres comandos con tuberías, redirección de la salida y ejecución en segundo plano Si el usuario introduce por teclado “command8”, la minishell debe ejecutar el comando du –ha . | grep 4\.0K > <output_file> &. Este commando es el mismo que el del ejercicio 6, pero debe ser ejecutado en Segundo plano (background). Esto significa que la minishell no espera a la finalización del comando para solicitar un nuevo comando inmediatamente tras la creación del proceso. minishell>command8 output_file.txt [3459] minishell> -- command is currently on execution while minishell is asking for another command -- Notas: Utilizar una tubería para redirigir la salida de la primera parte del comando a la entrada de la segunda parte del comando (pipe, dup y close). El usuario debe introducir el nombre del fichero de salida en la misma línea que el comando. Se puede invocar la función scanf dos veces: la primera obtendrá el nombre del comando y la segunda obtendrá el nombre del fichero. La salida de la segunda parte del comando se redirigirá a dicho fichero. Se debe utilizar las funciones open, dup y close. NO UTILIZAR wait o waitpid en el código del padre para esperar hasta que el comando finalice. El proceso principal de la minishell realizará el fork de todos los procesos hijos. En lugar de realizar la espera, se debe imprimir el PID del proceso que ejecuta la última parte del comando (grep) utilizando el siguiente formato: “[%d]\n”, e inmediatamente después solicitar al usuario el siguiente comando a ejecutar. El programa debe devolver -1 si hay algún problema en cualquiera de las llamadas al sistema. Los procesos zombie que queden tras las ejecuciones en background serán recogidos por la minishell cuando ejecuten otro comando en primer plano. 11 1.1.9. Ejercicio 9: manejo de señales Si el usuario pulsa Ctl+Z durante la ejecución de un comando, la minishell debe imprimir el mensaje: Executing command <name of the command>. minishell>command7 output_file.txt error_file.txt -- executing… -- ^Z -- Ctrl-Z pressed -- Executing command command7 -- executing… -- Notas: Crear una variable que almacene el comando actual en ejecución. Actualizar dicha variable cada vez que se ejecuta un comando. Utilizar signal para configurar una función como manejador de la señal SIGTSTP. Imprimir el mensaje requerido en dicha función. 12 1.2. Código inicial Para facilitar la realización de esta práctica se dispone del fichero p2_process_2014.zip que contiene código fuente de apoyo. Para extraer su contenido ejecutar lo siguiente: unzip p2_process_2014.zip Al extraer su contenido, se crea el directorio p2_process_2014/, donde se debe desarrollar la práctica. Dentro de este directorio se habrán incluido los siguientes ficheros: Makefile Fichero fuente para la herramienta make. NO debe ser modificado. Con él se consigue la recompilación automática sólo de los ficheros fuente que se modifiquen. Utilice $ make para compilar los programas, y $ make clean para eliminar los archivos compilados. minishell.c Fichero de código fuente en el que se debe codificar la minishell. format.sh Shell script que permite comprobar si los ficheros de entrega cumplen las normas especificadas de formato. 1.3. Comprobador de formato El script format.sh verifica que la entrega del alumno sigue estos requisitos: Requisitos sobre el nombre del fichero a entregar. Formato de compresión y estructura del fichero a entregar. Ausencia de errores de compilación. Para obtener más información sobre los contenidos del fichero format.sh puede ser abierto y analizado. Es obligatorio utilizar este comprobador de formato. El comando para ejecutarlo es el siguiente (se debe ejecutar en Linux): sh format.sh <fichero_a_entregar.zip> Ejemplo: $ sh format.sh ssoo_p2_100254896_10004714.zip El comprobador de formato imprimirá por pantalla mensajes acerca de si el formato requerido se cumple o no. 13 2. Entrega 2.1. Plazo de entrega y procedimiento La fecha límite de entrega de la práctica se podrá consultar en AULA GLOBAL. La entrega de las prácticas ha de realizarse de forma electrónica. En AULA GLOBAL se habilitarán unos enlaces a través de los cuales podrá realizar la entrega de las prácticas. En concreto, se habilitará un entregador para el código de la práctica, y otro de tipo TURNITIN para la memoria de la práctica. 2.2. Ficheros a entregar Se debe entregar un archivo comprimido en formato zip con el nombre ssoo_p2_AAAAAAAAA_BBBBBBBBB.zip donde A…A y B…B son los NIAs de los integrantes del grupo. En caso de realizar la práctica en solitario, el formato será ssoo_p2_AAAAAAAAA.zip. El archivo zip se entregará en el entregador correspondiente al código de la práctica. El archivo debe contener: o Makefile o minishell.c Para comprimir mediante línea de comandos, se puede utilizar el comando: zip ssoo_p2_AAAAAAAAA_BBBBBBBBB minishell.c La memoria se entregará en formato PDF en un fichero llamado ssoo_p2_AAAAAAAAA_BBBBBBBBB.pdf. Solo se corregirán y calificarán memorias en formato pdf. Tendrá que contener al menos los siguientes apartados: Descripción del código detallando las principales funciones implementadas. NO incluir código fuente de la práctica en este apartado. Cualquier código será automáticamente ignorado. Batería de pruebas utilizadas y resultados obtenidos. Se dará mayor puntuación a pruebas avanzadas, casos extremos, y en general a aquellas pruebas que garanticen el correcto funcionamiento de la práctica en todos los casos. Hay que tener en cuenta: o Que un programa compile correctamente y sin advertencias (warnings) no es garantía de que funcione correctamente. o Evite pruebas duplicadas que evalúan los mismos flujos de programa. La puntuación de este apartado no se mide en función del número de pruebas, sino del grado de cobertura de las mismas. Es mejor pocas 14 pruebas que evalúan diferentes casos a muchas pruebas que evalúan siempre el mismo caso. Conclusiones, problemas encontrados, cómo se han solucionado, y opiniones personales. Se puntuará también los siguientes aspectos relativos a la presentación de la práctica: Debe contener portada, con los autores de la práctica y sus NIAs. Debe contener índice de contenidos. La memoria debe tener números de página en todas las páginas (menos la portada). El texto de la memoria debe estar justificado. El archivo pdf se entregará en el entregador correspondiente la memoria de la práctica (entregador TURNITIN). NOTA: La única versión registrada de su práctica es la última entregada. La valoración de esta es la única válida y definitiva. 15 3. Normas 1) Las prácticas que no compilen o que no se ajusten a la funcionalidad y requisitos planteados, obtendrán una calificación de 0. 2) El entorno de pruebas de cara la evaluación de la práctica será guernika. Asegúrese de que su práctica funciona correctamente en guernika mediante ssh o bien en los laboratorios del departamento de informática. 3) Se prestará especial atención a detectar funcionalidades copiadas entre dos prácticas. En caso de encontrar implementaciones comunes en dos prácticas, los alumnos involucrados (copiados y copiadores) obtendrán una calificación de cero en la práctica, siendo incompatible con el seguimiento de la evaluación continua por normativa. 4) Los programas deben compilar sin warnings. De lo contrario, se penalizará la nota de la práctica. 5) Un programa no comentado, obtendrá una calificación de 0. 6) La entrega de la práctica se realizará a través de Aula Global, tal y como se detalla en el apartado Entrega de este documento. No se permite la entrega a través de correo electrónico sin autorización previa. 7) Se debe respetar en todo momento el formato de la entrada y salida que se indica en cada programa a implementar. 8) Se debe realizar un control de errores en cada uno de los programas. 9) Una práctica que no supere el corrector de formato recibirá una penalización en la nota. Los programas entregados que no sigan estas normas no se considerarán aprobados. 16 4. Bibliografía - El lenguaje de programación C: diseño e implementación de programas Félix García, Jesús Carretero, Javier Fernández y Alejandro Calderón. Prentice-Hall, 2002. - The UNIX System S.R. Bourne Addison-Wesley, 1983. - Advanced UNIX Programming M.J. Rochkind Prentice-Hall, 1985. - Sistemas Operativos: Una visión aplicada Jesús Carretero, Félix García, Pedro de Miguel y Fernando Pérez. McGraw-Hill, 2001. - Programming Utilities and Libraries SUN Microsystems, 1990. - Unix man pages (man function) Practicas/SSOO_g_ii_p1_llamadas_al_sistema_13-14.pdf Área de Arquitectura y Tecnología de Computadores Universidad Carlos III de Madrid SISTEMAS OPERATIVOS Práctica 1. Llamadas al sistema operativo Grado de Ingeniería en Informática Curso 2013/2014 Departamento de Informática Grado en Ingeniería Informática Sistemas Operativos (2013-2014) Práctica 1 - Llamadas al sistema operativo Índice 1.Enunciado de la Práctica.....................................................................................3 2.Entrega................................................................................................................8 3.Normas..............................................................................................................10 4.Anexo (Llamadas al sistema).............................................................................11 5.Bibliografía........................................................................................................14 2 Departamento de Informática Grado en Ingeniería Informática Sistemas Operativos (2013-2014) Práctica 1 - Llamadas al sistema operativo 1. Enunciado de la Práctica Esta práctica permite al alumno familiarizarse con las llamadas al sistema operativo (especialmente, el sistema de ficheros) siguiendo el estándar POSIX. Unix permite efectuar llamadas al sistema directamente desde un programa realizado en un lenguaje de alto nivel, que para esta práctica será el lenguaje C. La mayor parte de las entradas/salidas (E/S) sobre ficheros en Unix pueden realizarse utilizando solamente cinco llamadas: open, read, write, lseek y close. Para el kernel del sistema operativo, todos los archivos abiertos son identificados por medio de descriptores de archivo. Un descriptor de archivo es un entero no negativo. Cuando abrimos, open, un archivo que ya existe, el núcleo devuelve un descriptor de archivo al proceso. Cuando queremos leer o escribir de/en un archivo, identificamos el archivo con el descriptor de archivo que fue devuelto por la llamada anteriormente descrita. Cada archivo abierto tiene una posición de lectura/escritura actual ("current file offset"). Está representado por un entero no negativo que mide el número de bytes desde el comienzo del archivo. Las operaciones de lectura y escritura comienzan normalmente en la posición actual y provocan un incremento en dicha posición, igual al número de bytes leídos o escritos. Por defecto, esta posición es inicializada a 0 cuando se abre un archivo, a menos que se especifique la opción O_APPEND. La posición actual (current_offset) de un archivo abierto puede cambiarse explícitamente utilizando la llamada al sistema lseek. Para manipular directorios, se pueden utilizar las llamadas al sistema opendir, readdir y closedir. Un directorio abierto se identifica con un descriptor de directorio, que es un puntero a un tipo DIR (DIR*). Cuando abrimos un directorio con opendir, el núcleo devuelve un descriptor de directorio, sobre el cual se pueden leer las entradas de dicho directorio mediante llamadas a la función readdir. La llamada readdir devuelve una entrada de directorio en un puntero a una estructura dirent (struct dirent*). Dicha estructura contendrá los campos correspondientes a esa entrada como el nombre de la entrada, o el tipo (si es un fichero normal, si es otro directorio, enlaces simbólicos, etc.). Sucesivas llamadas a la función readdir irán devolviendo las sucesivas entradas de un directorio abierto. 3 Departamento de Informática Grado en Ingeniería Informática Sistemas Operativos (2013-2014) Práctica 1 - Llamadas al sistema operativo 1.1. Descripción de la Práctica Se pretende implementar tres programas en C que utilicen las llamadas al sistema anteriormente descritas. Dichos programas serán mywc, myenv y myishere. Para ello, dispondrán de los correspondientes ficheros de código mywc.c, myenv.c y myishere.c. mywc El primer programa, mywc, abrirá un fichero especificado como argumento, contará el número de líneas, palabras y bytes del mismo, y mostrará estas cuentas por la salida estándar (la consola) utilizando las llamadas al sistema que considere oportunas. Para ello: • Abrirá el fichero pasado como parámetro. • Leerá los contenidos del fichero de byte en byte. • Actualice los contadores en base a los bytes leídos. Se entiende que dos líneas están separadas por el carácter '\n', mientras que dos palabras pueden estar separadas por los caracteres ' ' o '\t'. No habrá más de un espacio o salto de línea sucesivo. • Mostrará los resultados por la salida estándar, seguidos del nombre del fichero. Separe cada valor del siguiente con un espacio. • Finalmente cerrará el fichero. ./mywc f1.txt 6 25 1048 f1.txt Uso: ./mywc <fichero de entrada> Requisitos: • El programa debe mostrar el número de líneas, palabras y bytes por consola, seguidos del nombre del fichero leído. • El programa mostrara los datos en el siguiente formato: <líneas><espacio><palabras><espacio><bytes><espacio><nombre fichero>. • El programa debe devolver -1 si no se le ha pasado ningún argumento de entrada. • El programa debe devolver -1 si hubo un error al abrir el fichero (e.g. el fichero no existe). • El programa debe devolver 0 si todo funcionó correctamente. 4 Departamento de Informática Grado en Ingeniería Informática Sistemas Operativos (2013-2014) Práctica 1 - Llamadas al sistema operativo myenv El segundo programa, myenv, guardará en un fichero las variables de entorno almacenadas en la variable environ, proporcionada en el programa. Para ello: • Abrirá el fichero pasado como parámetro. • Leerá las entradas de la variable de una en una. • Guardará dichas variables en el fichero. • Finalmente cerrará el fichero. ./myenv salida.txt Uso: ./myenv <fichero de salida> Requisitos: • El programa debe almacenar todas las entradas de la variable, en el orden en que estén almacenadas. • El programa debe separar cada entrada por un salto de línea (\n). • El programa debe devolver -1 si no se le ha pasado ningún argumento de entrada. • El programa debe devolver -1 si hubo un error al abrir el fichero (e.g. el fichero no existe). • El programa debe devolver 0 si todo funcionó correctamente. Notas: • El formato de la variable de entrono environ es un array de cadenas de caracteres, por tanto, cada posición del array constará de un array de caracteres terminado en ‘\0’. • La última posición del array environ apuntará a NULL. • El contenido del fichero generado por el programa será similar a la salida del comando env. 5 Departamento de Informática Grado en Ingeniería Informática Sistemas Operativos (2013-2014) Práctica 1 - Llamadas al sistema operativo myishere El tercer programa, myishere, abrirá un directorio pasado como parámetro y buscará en el mismo si existe un fichero cuyo nombre también se pasará como parámetro. Para ello: • Abrirá el directorio pasado como parámetro mediante la llamada al sistema correspondiente. • Luego, leerá las entradas del directorio sucesivamente mediante readdir hasta que o bien se encuentre una entrada cuyo nombre coincida con el parámetro, o bien se terminen las entradas. • Si el nombre se ha localizado, se imprimirá por pantalla el mensaje “File <nombre a buscar> is in directory <nombre directorio>”. En caso de no haberse localizado, se imprimirá por pantalla el mensaje “File <nombre a buscar> is not in directory <nombre directorio>”. • Finalmente cerrará el directorio. ../myishere /tmp ishere.txt File ishere.txt is in directory /tmp ../myishere /tmp isnothere.txt File isnothere.txt is not in directory /tmp Uso: ./myishere <directorio> <nombre de fichero> Requisitos: • El programa deberá poder revisar un directorio cualquiera y comprobar si alguna de sus entradas coincide con el nombre que se desea localizar. • El programa deberá mostrar uno de los dos mensajes descritos anteriormente, según corresponda. • El programa debe devolver -1 si hubo un error al abrir el directorio. • El programa debe devolver un 0 si todo funcionó correctamente (se entiende que el programa funciona correctamente si es capaz de determinar que el fichero está o no en el directorio sin que se produzcan errores). Notas: • La librería string.h contiene una función de comparación de cadenas llamada strcmp. 6 Departamento de Informática Grado en Ingeniería Informática Sistemas Operativos (2013-2014) Práctica 1 - Llamadas al sistema operativo 1.2. Código Fuente de Apoyo Para facilitar la realización de esta práctica se dispone del fichero p1_llamadas_2014.tgz que contiene código fuente de apoyo. Para extraer su contenido ejecutar lo siguiente: tar zxvf p1_llamadas_2014.tgz Al extraer su contenido, se crea el directorio p1_llamadas/, donde se debe desarrollar la práctica. Dentro de este directorio se habrán incluido los siguientes ficheros: Makefile Fichero fuente para la herramienta make. NO debe ser modificado. Con él se consigue la recompilación automática sólo de los ficheros fuente que se modifiquen. Utilice $ make para compilar los programas, y $ make clean para eliminar los archivos compilados. mywc.c Fichero fuente de C en donde los alumnos deberán codificar el programa mywc. myenv.c Fichero fuente de C en donde los alumnos deberán codificar el programa myenv. myishere.c Fichero fuente de C en donde los alumnos deberán codificar el programa myishere. format.sh Shell script que permite comprobar si los ficheros de entrega cumplen las normas especificadas de formato. 1.3. Corrector de formato proporcionado Se proporciona a los alumnos el shell script format.sh que verifica que el formato del entregable de la práctica es el correcto (sigue las especificaciones de nombrado, y está bien comprimido). También realiza una prueba básica de formato para aquellos programas solicitados en la práctica que muestran algo por consola. El script del corrector contiene comentarios que describen su funcionamiento. El corrector se deberá ejecutar en las máquinas Linux de las aulas informáticas de la universidad. El comando para ejecutar el corrector es el siguiente: sh format.sh <entregable.zip> Siendo entregable.zip el fichero que se va a entregar por aula global (ver siguiente apartado). Ejemplo: $ sh format.sh ssoo_p1_100254896_10004714.zip El corrector imprimirá mensajes por pantalla indicando si el formato es o no correcto para cada punto revisado. 7 Departamento de Informática Grado en Ingeniería Informática Sistemas Operativos (2013-2014) Práctica 1 - Llamadas al sistema operativo 2. Entrega 2.1. Plazo de entrega La fecha límite de entrega de la práctica se podrá consultar en AULA GLOBAL. 2.2. Procedimiento de entrega de las prácticas La entrega de las prácticas ha de realizarse de forma electrónica. En AULA GLOBAL se habilitarán unos enlaces a través de los cuales podrá realizar la entrega de las prácticas. En concreto, se habilitará un entregador para el código de la práctica, y otro de tipo TURNITIN para la memoria de la práctica. 2.3. Documentación a Entregar Se debe entregar un archivo comprimido en formato zip con el nombre ssoo_p1_AAAAAAAAA_BBBBBBBBB.zip donde A…A y B…B son los NIAs de los integrantes del grupo. En caso de realizar la práctica en solitario, el formato será ssoo_p1_AAAAAAAAA.zip. El archivo zip se entregará en el entregador correspondiente al código de la práctica. El archivo debe contener: o Makefile o mywc.c o myenv.c o myishere.c Para comprimir mediante línea de comandos, se puede utilizar el comando: zip ssoo_p1_AAAAAAAAA_BBBBBBBBB Makefile mywc.c myenv.c myishere.c La memoria se entregará en formato PDF en un fichero llamado ssoo_p1_AAAAAAAAA_BBBBBBBBB.pdf. Solo se corregirán y calificarán memorias en formato pdf. Tendrá que contener al menos los siguientes apartados: • Descripción del código detallando las principales funciones implementadas. NO incluir código fuente de la práctica en este apartado. Cualquier código será automáticamente ignorado. • Batería de pruebas utilizadas y resultados obtenidos. Se dará mayor puntuación a pruebas avanzadas, casos extremos, y en general a aquellas pruebas que garanticen el correcto funcionamiento de la práctica en todos los casos. Hay que tener en cuenta: 8 Departamento de Informática Grado en Ingeniería Informática Sistemas Operativos (2013-2014) Práctica 1 - Llamadas al sistema operativo o Que un programa compile correctamente y sin advertencias (warnings) no es garantía de que funcione correctamente. o Evite pruebas duplicadas que evalúan los mismos flujos de programa. La puntuación de este apartado no se mide en función del número de pruebas, sino del grado de cobertura de las mismas. Es mejor pocas pruebas que evalúan diferentes casos a muchas pruebas que evalúan siempre el mismo caso. • Conclusiones, problemas encontrados, cómo se han solucionado, y opiniones personales. Se puntuará también los siguientes aspectos relativos a la presentación de la práctica: • Debe contener portada, con los autores de la práctica y sus NIAs. • Debe contener índice de contenidos. • La memoria debe tener números de página en todas las páginas (menos la portada). • El texto de la memoria debe estar justificado. El archivo pdf se entregará en el entregador correspondiente la memoria de la práctica (entregador TURNITIN). NOTA: La única versión registrada de su práctica es la última entregada. La valoración de esta es la única válida y definitiva. 9 Departamento de Informática Grado en Ingeniería Informática Sistemas Operativos (2013-2014) Práctica 1 - Llamadas al sistema operativo 3. Normas 1) Las prácticas que no compilen o que no se ajusten a la funcionalidad y requisitos planteados, obtendrán una calificación de 0. 2) Se prestará especial atención a detectar funcionalidades copiadas entre dos prácticas. En caso de encontrar implementaciones comunes en dos prácticas, los alumnos involucrados (copiados y copiadores) obtendrán una calificación de cero en la práctica, siendo incompatible con el seguimiento de la evaluación continua por normativa. 3) Los programas deben compilar sin warnings. De lo contrario, se penalizará la nota de la práctica. 4) Un programa no comentado, obtendrá una calificación de 0. 5) La entrega de la práctica se realizará a través de Aula Global, tal y como se detalla en el apartado Entrega de este documento. No se permite la entrega a través de correo electrónico sin autorización previa. 6) Se debe respetar en todo momento el formato de la entrada y salida que se indica en cada programa a implementar. 7) Se debe realizar un control de errores en cada uno de los programas. 8) Una práctica que no supere el corrector de formato recibirá una penalización en la nota. Los programas entregados que no sigan estas normas no se considerarán aprobados. 10 Departamento de Informática Grado en Ingeniería Informática Sistemas Operativos (2013-2014) Práctica 1 - Llamadas al sistema operativo 4. Anexo (Llamadas al sistema). Las llamadas al sistema proporcionan la interfaz entre el sistema operativo y un programa en ejecución. UNIX permite efectuar llamadas al sistema directamente desde un programa realizado en un lenguaje de alto nivel, en particular en lenguaje C, en cuyo caso las llamadas se asemejan a llamadas a funciones, tal y como si estuvieran definidas en una biblioteca estándar. El formato general de una llamada al sistema es: status = funcion_estandar (arg1, arg2,.....) En caso de realizar una llamada sin éxito, devolvería en la variable status un valor -1. En la variable global errno se coloca el número de error, con el cual podemos obtener la asociación del error con lo que realmente ha ocurrido en el fichero errno.h, (contenido en la ruta: /usr/src. En linux : /usr/src/linux/include/asm/errno.h). 4.1. Llamadas al sistema relacionadas con archivos int open(const char * path, into flag, ...) Abre o crea un fichero especificado por path. El fichero abierto puede utilizarse para lectura, escritura, o ambas, en función de lo especificado por flag. Devuelve un descriptor de fichero que se puede utilizar para la lectura o escritura en el archivo. Más ayuda en: man 2 open int close(int fildes) Cierra un archivo abierto anteriormente asociado al descriptor fildes. Si n = -1→ Error al cerrar el fichero. Más ayuda en: man 2 close ssize_t read(int fildes, void * buf, size_t nbyte) Intenta leer de un archivo (cuyo descriptor de fichero fildes se obtuvo de abrirlo) tantos bytes como indica nbyte, colocando la información leída a partir de la dirección de memoria buf. Devuelve el número de bytes leídos (que puede ser menor o igual a nbyte). Si retorno = 0 → Fin de fichero (EOF). Si retorno = -1 → Error de lectura. Más ayuda en: man 2 read 11 Departamento de Informática Grado en Ingeniería Informática Sistemas Operativos (2013-2014) Práctica 1 - Llamadas al sistema operativo ssize_t write(int fildes, const void * buf, size_t nbyte) Intenta escribir en un archivo (cuyo descriptor de fichero fildes se obtuvo de abrirlo) tantos bytes como indica nbyte, tomándolos de la dirección de memoria indicada buf. Devuelve en n el número de bytes que realmente se han escrito (que puede ser menor o igual a nbyte). Si retorno = -1 → Error de escritura. Cada write (así como cada read), actualiza automáticamente la posición actual del fichero que se usa para determinar la posición en el archivo del siguiente write o read. Más ayuda en: man 2 write off_t lseek(int fildes, off_t offset, int whence) Modifica el valor del apuntador del descriptor fildes en el archivo, a la posición explícita en desplazamiento a partir de la referencia impuesta en origen, de forma que las llamadas read o write pueden iniciarse en cualquier parte del archivo. Si retorno = -1 → Error de posicionamiento. El parámetro whence puede tomar los siguientes valores: • SEEK_SET → desde el principio del fichero. • SEEK_CUR → desde la posición actual. • SEEK_END → desde el final del fichero. El parámetro offset se expresa en bytes, y toma un valor positivo o negativo. Ejemplo: a b c d e f g h i lseek(5,4,SEEK_SET) → Al avanzar 4 bytes, la siguiente lectura sería la "e". El descriptor del fichero abierto 'fd' es 5. Más ayuda en: man 2 lseek 4.2. Llamadas al sistema relacionadas con directorios DIR * opendir(const char * dirname) Abre un directorio existente especificado por dirname. Devuelve un descriptor de directorio que se puede utilizar para la lectura de las entradas de dicho directorio. Si retorno = NULL Error al abrir el directorio. Más ayuda en: man opendir 12 Departamento de Informática Grado en Ingeniería Informática Sistemas Operativos (2013-2014) Práctica 1 - Llamadas al sistema operativo struct dirent * readdir(DIR * dirp) Lee la siguiente entrada de un directorio (cuyo descriptor de directorio dirp se obtuvo al abrirlo. La estructura dirent contiene un campo d_name (char * d_name) con el nombre de la entrada y un capo d_type (unsigned char d_type) con el tipo de la entrada (fichero, otro directorio, etc.). Siguientes llamadas a esta función sobre el mismo descriptor de directorio devuelven las subsiguientes entradas. Cuando no quedan más entradas por devolver, esta llamada devuelve NULL. Más ayuda en: man readdir int closedir(DIR * dirp) Cierra un directorio abierto anteriormente. Si retorno = -1→ Error al cerrar el directorio. Más ayuda en: man closedir 4.3. Manual (man function). man es el paginador del manual del sistema, es decir, permite buscar información sobre un programa, una utilidad o una función. Véase el siguiente ejemplo: man 2 open Una página de manual tiene varias partes. Éstas están etiquetadas como NOMBRE, SINOPSIS, DESCRIPCIÓN, OPCIONES, FICHEROS, VÉASE TAMBIÉN, BUGS, y AUTOR. En la etiqueta de SINOPSIS se recogen las librerías (identificadas por la directiva #include) que se deben incluir en el programa en C del usuario para poder hacer uso de las funciones correspondientes. Para salir de la página mostrada, basta con pulsar la tecla 'q'. Las formas más comunes de usar man son las siguientes: • man sección elemento: Presenta la página de elemento disponible en la sección del manual. • man -a elemento: Presenta, secuencialmente, todas las páginas de elemento disponibles en el manual. Entre página y página se puede decidir saltar a la siguiente o salir del paginador completamente. • man -k palabra-clave: Busca la palabra-clave entre las descripciones breves y las páginas de manual y presenta todas las que casen. 13 Departamento de Informática Grado en Ingeniería Informática Sistemas Operativos (2013-2014) Práctica 1 - Llamadas al sistema operativo 5. Bibliografía - El lenguaje de programación C: diseño e implementación de programas Félix García, Jesús Carretero, Javier Fernández y Alejandro Calderón. Prentice-Hall, 2002. - The UNIX System S.R. Bourne Addison-Wesley, 1983. - Advanced UNIX Programming M.J. Rochkind Prentice-Hall, 1985. - Sistemas Operativos: Una visión aplicada Jesús Carretero, Félix García, Pedro de Miguel y Fernando Pérez. McGraw-Hill, 2001. - Programming Utilities and Libraries SUN Microsystems, 1990. - Unix man pages (man function) 14 1. Enunciado de la Práctica 1.1. Descripción de la Práctica mywc myenv myishere 1.2. Código Fuente de Apoyo 1.3. Corrector de formato proporcionado 2. Entrega 2.1. Plazo de entrega 2.2. Procedimiento de entrega de las prácticas 2.3. Documentación a Entregar 3. Normas 4. Anexo (Llamadas al sistema). 4.1. Llamadas al sistema relacionadas con archivos 4.2. Llamadas al sistema relacionadas con directorios 4.3. Manual (man function). 5. Bibliografía
Compartir