Logo Studenta

UC3M _ Doble Grado en Ingeniería Informática y ADE _ Sistemas operativos _ Practicas_

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

Continuar navegando