Guia Laboratorio 4 SO
Guia Laboratorio 4 SO
Guia Laboratorio 4 SO
GUIA No. 4
CONCURRENCIA Y SINCRONIZACION ENTRE PROCESOS
INTRODUCCIÓN
El laboratorio significa aprendizaje mediante la experiencia directa del estudiante con los elementos que
constituyen el mismo y la interacción sobre estos elementos, para obtener resultados, adquirir destrezas e
interpretación en su manejo (por ejemplo aprender a manejar un sistema operativo de licencia libre).
Este trabajo sirve de guía para las prácticas en el “Lab. De Computación” perteneciente a la
Coordinación de la Carrera Ingeniería de Sistemas de la Universidad Nacional Experimental Politécnica de
la Fuerza Armada Nacional.
El Docente y el Auxiliar:
El Estudiante:
LABORATORIO DE SO
AUTOR: ING. ANA LORENA FREITEZ
3
PRACTICA No.4
PRE - LABORATORIO
1. ACTIVIDAD DE PRE PRACTICA
2. OBJETIVO:
a) Explorar el uso de hilos como herramienta básica para aprovechar la concurrencia en los
procesos.
b) Identificar el uso de la técnica de memoria compartida como un mecanismo de comunicación
efectivo tanto entre hilos como entre procesos.
3. MARCO TEÓRICO
HILOS Y COMUNICACIÓN (MEMORIA COMPARTIDA)
3.1 Hilos
Los hilos son el medio por el cual un proceso puede implementar concurrencia. Éstos permiten que
un proceso posea varios caminos de ejecución y a su vez compartan cierta región de memoria de manera
directa. Por otro lado, en un sistema con KLT (Kernel Level Thread) y con multiprocesamiento o
multithreading (por ejemplo, el hyperthreading de Intel), los hilos aprovecharían al máximo los recursos de
hardware disponibles y aumentarían considerablemente el desempeño de una aplicación.
Generalmente, cada sistema operativo tiene una forma propia de enfrentar el desafío de la
implementación de los hilos. A continuación se presenta un resumen de dos lecturas tomadas del libro de
Silberschatz [1] relacionadas con la implementación de los hilos en Windows XP y en Linux.
a) Hilos en Windows XP
El API Win32 es el API primario para la familia de sistemas operativos Windows. En Windows XP
las aplicaciones corren como un proceso separado y cada proceso puede contener uno o más hilos. Windows
XP usa un mapeo uno a uno, donde cada hilo a nivel de usuario se mapea a un hilo asociado al kernel. Sin
embargo, Windows XP también provee soporte para una librería de hilos, la cual provee la funcionalidad del
modelo mucho a muchos. Al usar la librería de hilos cualquier hilo perteneciente a un proceso puede acceder
al espacio de direcciones del proceso.
Los componentes generales de un hilo en Windows XP son:
Un thread ID, identificador único para cada hilo.
LABORATORIO DE SO
AUTOR: ING. ANA LORENA FREITEZ
4
LABORATORIO DE SO
AUTOR: ING. ANA LORENA FREITEZ
5
Por ejemplo, si clone es llamado con las banderas CLONE_FS, CLONE_VM, CLONE_SIGHAND,
y CLONE_FILES, las tareas padre e hija, compartirán la misma información del sistema de archivos (como
el actual directorio de trabajo), el mismo espacio de memoria, los mismos manejadores de señales y el
mismo conjunto de archivos abiertos. Usar el llamado al sistema clone() de este modo es equivalente a crear
un hilo como se ha descrito de manera teórica, ya que la tarea padre comparte la mayoría de sus recursos con
su tarea hija. Sin embargo, si ninguna de esas banderas es fijada cuando se hace el llamado a clone(), ningún
intercambio es realizado y la funcionalidad será similar a la proporcionada por la llamada al sistema fork().
El nivel de variación de intercambio es posible debido a la manera como una tarea es representada en
el kernel de Linux. Solo existe una estructura de datos en el kernel para cada tarea en el sistema
(específicamente, struct task_struct). Esta estructura de datos en lugar de almacenar datos para la tarea,
contiene apuntadores a otras estructuras de datos donde la información está almacenada, por ejemplo
estructuras de datos que representan la lista de archivos abiertos, información del manejo de señales y la
memoria virtual. Cuando fork() es invocado, una nueva tarea es creada y junto con ella una copia de todas
las estructuras de datos del proceso padre. Una nueva tarea se crea también con el llamada al sistema
clone(), la diferencia radica es que en lugar de una copia de todas las estructuras de datos, la nueva tarea
apunta a las estructuras de datos de la tarea padre, dependiendo del conjunto de opciones pasadas en el
llamado a clone().
LABORATORIO DE SO
AUTOR: ING. ANA LORENA FREITEZ
6
Para los proceso la situación cambia, ya que éstos no poseen a priori, ningún espacio de memoria
compartido, por lo que se hace necesaria la intervención del sistema operativo para asignar un espacio de
memoria que sea visible por los procesos que se desean comunicar.
En ambos casos tras la definición de un espacio de memoria se hace necesario sincronizar el acceso a
la misma, pues se puede presentar una condición de carrera que altera el buen funcionamiento de la
aplicación (para profundizar en este concepto remítase al material de clase o al capítulo 2 del libro de
Tanenbaum [2]).
3.3 Semáforos
En la clase de sistemas operativos se abordó el uso de semáforos como mecanismo de sincronización
entre procesos e hilos. El concepto de semáforo se aplica muy similar tanto en procesos como en hilos
dentro de un S.O.
Las primitivas wait y signal se suponen atómicas, es decir, no pueden ser interrumpidas y cada rutina
puede considerarse como un paso indivisible. Una versión más limitada es el semáforo binario, que sólo
puede tomar los valores 0 y 1. En principio los semáforos binarios son más sencillos de implementar y
tienen la misma potencia de expresión que los semáforos generales. Tanto en los semáforos como en los
semáforos binarios se emplea una cola para mantener los procesos esperando en el semáforo. La política
más equitativa mediante la cual se quitan los procesos de dicha cola es la FIFO. La única exigencia estricta
es que un proceso no debe quedar retenido en la cola de un semáforo indefinidamente porque otros procesos
tengan preferencia.
Generalmente operadores como WAIT y SIGNAL operan en los semáforos de la siguiente manera.
Cuando un proceso ejecuta un operador WAIT que tiene un valor de semáforo en 0, ese proceso se bloquea;
si el valor es mayor que cero, el valor del semáforo es disminuido en 1 y el proceso continua. Cuando un
proceso ejecuta un operador SIGNAL y hay procesos bloqueados (WAITING), uno de estos procesos es
activado (puesto en la cola de listos). Si no hay procesos esperando el valor del semáforo se incrementa en 1.
Se asume que procesos bloqueados por semáforos pierden el procesador y entran en una cola de espera
(WAITING QUEUE) en vez de producir BUSY WAITING. También se asume que la cola de espera es
FIFO.
LABORATORIO DE SO
AUTOR: ING. ANA LORENA FREITEZ
7
4. DESARROLLO DE LA PRÁCTICA
LABORATORIO
Requisitos:
4.1 HILOS
Compile los siguientes ejercicios, analice el código y la salida. Para la compilar el código con la
librería pthread es necesario utilizar la opción –lpthread, como se muestra este ejemplo:
gcc codigo.c –o codigo -lpthread
a) Creación de un hilo:
#include <pthread.h>
#include <stdio.h>
}
if (is_prime) {
if (--n == 0)
return (void*) candidate;
}
++candidate;
}
return NULL;
}
int main () {
pthread_t thread;
int which_prime = 5000;
int prime;
/* Inicia el hilo, se requiere l número primo #5000. */
pthread_create (&thread, NULL, &compute_prime, &which_prime);
/* Puedo hacer algo mientras... si quiero */
/* Espero que el número sea calculado y me sea entregado. */
pthread_join (thread, (void*) &prime);
/* Imprimo el número entregado. */
printf("El número primo es %d.\n", prime);
return 0;
}
¿Cómo es el funcionamiento del código presentado?
Según lo visto en este ejercicio ¿Cuál es la forma de retornar valores desde un hilo? Explique de
manera clara y en sus propias palabras.
#define SHMSZ 27
main(){
char c;
int shmid;
key_t key;
char *shm, *s;
/*Nombre del segmento de memoria compartida = "1234".*/
key = 1234;
/* Se crea el segmento de memoria*/
if ((shmid = shmget(key, SHMSZ, IPC_CREAT | 0666)) < 0) {
LABORATORIO DE SO
AUTOR: ING. ANA LORENA FREITEZ
9
perror("shmget");
exit(1);
}
/* El programa se adhiere (attach) al segmento ya creado */
if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) {
perror("shmat");
exit(1);
}
/* Se ponen algunos datos en el segmento para que el proceso
cliente los lea */
s = shm;
for (c = 'a'; c <= 'z'; c++)
*s++ = c;
*s = NULL;
/* Por último, se espera a que el proceso cliente cambie el primer caracter
de la memoria compartida a '*' indicando que ya leyó la información */
while (*shm != '*')
sleep(1);
exit(0);
}
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#define SHMSZ 27
main() {
int shmid;
key_t key;
char *shm, *s;
/* Ubica el segmento */
if ((shmid = shmget(key, SHMSZ, 0666)) < 0) {
perror("shmget");
exit(1);
}
/* Se adhiere al segmento para poder hacer uso de él */
if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) {
perror("shmat");
exit(1);
}
/* Lee lo que el servidor puso en la memoria */
for (s = shm; *s != NULL; s++)
putchar(*s);
putchar('\n');
/* Finalmente, cambia el calor del primer caracter indicando que
LABORATORIO DE SO
AUTOR: ING. ANA LORENA FREITEZ
10
ha leído el segmento */
*shm = '*';
exit(0);
}
Consulte el uso de las funciones shmget, shmat, shmdt y shmctl. ¿Para qué sirven estas
funciones? ¿Qué argumentos reciben y para qué sirven estos argumentos? ¿Cuál es la forma
tradicional de usar estas funciones?
Analice el código anterior y verifique el uso y los parámetros pasados a las funciones
mencionadas anteriormente.
POST LABORATORIO
6. ACTIVIDAD POST – PRÁCTICA.
process dos;
var
lin: integer;
begin
for lin := 1 to 20 do
begin
wait(mutex);
nolineas :=
nolineas + 1;
signal(mutex)
end
LABORATORIO DE SO
AUTOR: ING. ANA LORENA FREITEZ
11
LABORATORIO DE SO
AUTOR: ING. ANA LORENA FREITEZ