SISTEMAS OPERATIVOS:

Documentos relacionados
SISTEMAS OPERATIVOS: COMUNICACIÓN Y SINCRONIZACIÓN ENTRE PROCESOS. Desarrollo de servidores concurrentes

SISTEMAS OPERATIVOS:

SISTEMAS OPERATIVOS: COMUNICACIÓN Y SINCRONIZACIÓN ENTRE PROCESOS. Hilos y mecanismos de comunicación y sincronización

Nº Mat. Calificación APELLIDOS NOMBRE. CURSO 4º GRUPO Julio 2014 ASIGNATURA: SISTEMAS INFORMÁTICOS INDUSTRIALES

Procesos ligeros. Arquitectura de Computadores II Universidad Carlos III de Madrid

Fundamentos de los Sistemas Operativos

BENEMERITA UNIVERSIDADD AUTONOMA DE PUEBLA FACULTAD DE CIENCIAS DE LA COMPUTACIÓN LICENCIATURA EN CIENCIAS DE LA COMPUTACIÓN

SISTEMAS OPERATIVOS:

Programación de Multitareas utilizando Hilos

Analista Universitario en Sistemas. Sistemas Operativos. Instituto Politécnico Superior THREADS

Sistemas Operativos 1

ASIGNATURA: SISTEMAS INFORMÁTICOS INDUSTRIALES. CURSO 4º GRUPO Octubre 2015

Programación Concurrente

SISTEMAS OPERATIVOS: Lección 4: Planificación de Procesos

Biblioteca de sistema

Tema 4 El paradigma cliente-servidor

Sistemas Operativos Primer Examen Parcial 13/07/15

Procesos e Hilos en C

Concurrencia en UNIX / LINUX. Introducción: Procesos e Hilos POSIX

Sistemas Operativos Primer Recuperatorio Parcial 1

Programación Concurrente

PARTE II PROGRAMACION CON THREADS EN C

Sincronización de Threads

Taller de pthreads. Sistemas Operativos. Verano de 2009

SISTEMAS OPERATIVOS: Lección 10: Gestión de Memoria Virtual

SISTEMAS OPERATIVOS: PROCESOS. Hilos y Procesos

Tema 4: Gestión de Procesos

Sistemas operativos: una visión aplicada. Capítulo 5 Comunicación y sincronización de procesos

Bloque I: Principios de sistemas operativos

Clases 04 y 05: Repaso de programación de sistemas basados en UNIX

Prácticas de Sistemas operativos

Sistemas Operativos. Procesos

Threads. Hilos - Lightweight process - Procesos ligeros

Programación Concurrente

Introducción a Sistemas Operativos: Concurrencia

UNIVERSIDAD AUTÓNOMA DE BAJA CALIFORNIA FACULTAD DE CIENCIAS PRACTICA DE PROCESOS HERRAMIENTAS

Procesos y Threads Procesos y Threads. Concurrencia Concurrencia Ventajas Ventajas. Rendimiento Rendimiento (paralelismo) (paralelismo)

Sistemas Operativos Práctica 3

Procesos e hilos: el downloader

Función monitoreo descriptor archivo #include <sys/types.h> #include<unistd.h> #include<errno.h> extern void procesamiento_datos(char *, int); void pr

MC Hilda Castillo Zacatelco PROCESOS

Funciones POSIX (I): Introducción

Bloque I: Principios de sistemas operativos

Tema III. Multihilo. Desarrollo de Aplicaciones para Internet Curso 12 13

Introducción general al Lenguaje C (2010/2011)

SISTEMAS OPERATIVOS: PROCESOS. Planificación de procesos

8. Vectores (arrays)

Funciones POSIX III Funciones POSIX III. No Nombrados Nombrados. sem_open sem_open. sem_close sem_close. sem_unlink sem_unlink

UNIVERSIDAD CARLOS III DE MADRID DEPARTAMENTO DE INFORMÁTICA INGENIERÍA EN INFORMÁTICA. ARQUITECTURA DE COMPUTADORES II 10 junio de 2006

Sistemas operativos: una visión aplicada. Capítulo 5 Comunicación y sincronización de procesos

IMPLEMENTACIÓN DE PILAS CON LISTAS EN C++

Prácticas de Sistemas operativos

2. Problema de Análisis y Diseño Orientado a Objetos (4 puntos - 25 minutos)

Sistemas Operativos I Manual de prácticas

Realizar el ejercicio anterior utilizando Punteros

- Bajo que condiciones el algoritmo de planifiación de procesos FIFO (FCFS) resultaría en el tiempo de respuesta promedio más pequeño?

Teoría. Procesos. Escuela Politécnica Superior Universidad Autónoma de Madrid 1

Prueba de Laboratorio Modelo B01 Semáforos y Memoria Compartida

Prácticas de Sistemas operativos

Elementos de un programa en C

Una clave Definición informal La clave debe contener una secuencia de una o más letras seguidas por uno o más dígitos

Tema 2 Comunicación y sincronización entre procesos

SISTEMAS OPERATIVOS: Lección 5: Hilos y Procesos

Estructuras de Datos Declaraciones Tipos de Datos

Sistemas Operativos sesión 12: tuberías

Introducción a la librería de desarrollo librawnet

Informática Electrónica Concurrencia

Equivalencia de herramientas. Implementar las primitivas de los semáforos a partir de las regiones críticas condicionales. (2.5pt)

ASIGNATURA: SISTEMAS INFORMÁTICOS INDUSTRIALES. CURSO 4º GRUPO Diciembre 2013

26/01/2010. Espera activa Semáforos Problemas clásicos de com. y sin. Servicios POSIX

Departamento de Automática

Sistemas operativos: una visión aplicada. Capítulo 3 Procesos

Fundamentos de los Sistemas Operativos. Tema 2. Procesos José Miguel Santos Alexis Quesada Francisco Santana

Ejercicio 1. Teoría [2,5 puntos]:

Sincronización de Hilos POSIX

PROGRAMACIÓN MULTITHREADING

Programación Estructurada

Entorno de programación de nivel 1: La librería PCAP

Boletín de ejercicios 2.2 Ejercicios sobre gestión básica de hilos

Tema 3. Concurrencia entre procesos

SISTEMAS OPERATIVOS: COMUNICACIÓN Y SINCRONIZACIÓN ENTRE PROCESOS. Procesos concurrentes y problemas en la comunicación y la sincronización

Plataformas de Tiempo Real

Nº Mat. Calificación APELLIDOS NOMBRE. CURSO 4º GRUPO Octubre 2014 ASIGNATURA: SISTEMAS INFORMÁTICOS INDUSTRIALES

Procesos e hilos: cálculo de

Tema 2: Clases y Objetos

Boletín 4- Procesos. Departamento de Lenguajes y Sistemas Informáticos

Arquitecturas cliente/servidor

Boletín 4- Procesos. Departamento de Lenguajes y Sistemas Informáticos

Contenido. P á g i n a 1

Redirecciones y Tuberías

ELO330: Programación de Sistemas: Certamen Final 8/11/2006 Certamen Final 100 minutos. Puede usar Apuntes. Todas las preguntas tienen igual puntaje.

Introducción y Gestión de Procesos

Sucesos asíncronos. dit. dit. Juan Antonio de la Puente DIT/UPM UPM UPM

SISTEMAS OPERATIVOS: Lección 11: Ficheros

Programación 1 Tema 2. Lenguaje de programación y ejecución de un programa

Soluciones a ejercicios de paralelismo y concurrencia

Nombre alumno: Ventajas: Inconvenientes:

Procesos e hilos. Pablo San Segundo (C-206)

LENGUAJE. Tema 1 - Introducción

Transcripción:

SISTEMAS OPERATIVOS: Lección 8: Desarrollo de servidores concurrentes Jesús Carretero Pérez Alejandro Calderón Mateos José Daniel García Sánchez Francisco Javier García Blas José Manuel Pérez Lobato Introducción y conceptos básicos María Gregoria Casares Andrés 1

ADVERTENCIA Este material es un simple guión de la clase: no son los apuntes de la asignatura. El conocimiento exclusivo de este material no garanbza que el alumno pueda alcanzar los objebvos de la asignatura. Se recomienda que el alumno ublice los materiales complementarios propuestos. 2

Contenido Servidores de pebciones. Solución basada en procesos. Solución basada en hilos bajo demanda. Solución basada en pool de hilos. 3

Servidor de pebciones En muchos contextos se desarrollan servidores de pebciones: Servidor Web. Servidor de Base de datos. Servidor de aplicaciones. Programa de intercambio de ficheros. Aplicaciones de mensajería. 4

Servidor SERVIDOR CLIENTE CLIENTE CLIENTE CLIENTE CLIENTE CLIENTE 5

Problema: Servidor de pebciones Un servidor recibe pebciones que debe procesar. Estructura de un servidor genérico: Recepción de pebción: Cada pebción requiere un cierto Bempo en operaciones de entrada/salida para ser recibida. Procesamiento de la pebción: Un cierto Bempo de procesamiento en CPU. Envío de respuesta: Un cierto Bempo de entrada/salida para contestar. 6

Una biblioteca para pruebas Para poder evaluar las soluciones hoy vamos a usar una biblioteca sencilla como base. Ideas: Simular la recepción de pebciones. Simular el procesamiento de pebciones. Simular el envío de respuestas. 7

Biblioteca base #ifndef PETICION_H #define PETICION_H struct peticion { long id; /* Resto de campos necesarios */ int tipo; }; #endif char url[80]; /*... */ typedef struct peticion peticion_t; void recibir_peticion (peticion_t * p); void responder_peticion (peticion_t * p); 8

Recepción de pebciones static long petid = 0; void recibir_peticion (peticion_t * p) { int delay; fprintf(stderr, "Recibiendo petición\n"); p->id = petid++; /* Simulación de tiempo de E/S */ delay = rand() % 5; sleep(delay); } fprintf(stderr,"petición %d recibida después de %d segundos\n", p->id, delay); 9

Recepción de pebciones static long petid = 0; void recibir_peticion (peticion_t * p) { int delay; fprintf(stderr, "Recibiendo petición\n"); p->id = petid++; } /* Simulación de tiempo de E/S */ delay = rand() % 5; sleep(delay); Aquí iría alguna llamada bloqueante para recibir fprintf(stderr,"petición %d recibida después la de petición %d segundos\n", (por ejemplo p->id, delay); de la red) 10

Envío de pebciones void responder_peticion (peticion_t * p) { int delay, i; double x; fprintf(stderr, "Enviando petición %d\n", p->id); /* Simulación de tiempo de procesamiento */ for (i=0;i<1000000;i++) { x = 2.0 * i; } /* Simulación de tiempo de E/S */ delay = rand() % 20; sleep(delay); } fprintf(stderr, "Petición %d enviada después de %d segundos\n", p->id, delay); 11

Envío de pebciones void responder_peticion (peticion_t * p) { int delay, i; double x; fprintf(stderr, "Enviando petición %d\n", p->id); } /* Simulación de tiempo de procesamiento */ for (i=0;i<1000000;i++) { x = 2.0 * i; } /* Simulación de tiempo de E/S */ delay = rand() % 20; sleep(delay); Aquí iría el procesamiento de la petición fprintf(stderr, "Petición %d enviada después Aquí de %d iría segundos\n", alguna llamada p->id, delay); bloqueante para responder a la petición 12

Una primera solución Ejecutar de modo indefinido la secuencia: Recibir una pebción. Procesar la pebción. #include "pe,cion.h int main() { pe,cion_t p; for (;;) { recibir_pe,cion(&p); responder_pe,cion(&p); } } return 0; 13

Problemas Llegada de pebciones. Si dos pebciones llegan al mismo Bempo Si una pebción llega mientras otra se está procesando UBlización de los recursos. Cómo será la ublización de la CPU? 14

Solución inicial con medición #include "pe,cion.h" #include <stdio.h> #include <,me.h> int main() { int i; const int MAX_PETICIONES = 5;,me_t t1,t2; double dif; pe,cion_t p; t1 =,me(null); for (i=0;i<max_peticiones;i++) { recibir_pe,cion(&p); responder_pe,cion(&p); } t2 =,me(null); dif = divime(t2,t1); prinw("tiempo: %lf\n",dif); } return 0; 15

Ejecución $ time./ej1 Recibiendo petición Petición 0 recibida después de 0 segundos Enviando petición 0 Petición 0 enviada después de 13 segundos Recibiendo petición Petición 1 recibida después de 3 segundos Enviando petición 1 Petición 1 enviada después de 2 segundos Recibiendo petición Petición 2 recibida después de 4 segundos Enviando petición 2 Petición 2 enviada después de 0 segundos Recibiendo petición Petición 3 recibida después de 3 segundos Enviando petición 3 Petición 3 enviada después de 12 segundos Recibiendo petición Petición 4 recibida después de 1 segundos Enviando petición 4 Petición 4 enviada después de 16 segundos Tiempo: 54.000000 real user sys 0m54.164s 0m0.061s 0m0.046s 16

Comparación Normal Procesos Hilo x petición Pool de hilos 54 seg. 17

Contenido Servidores de pebciones. Solución basada en procesos. Solución basada en hilos bajo demanda. Solución basada en pool de hilos. 18

Primera idea Cada vez que llega una pebción se crea un proceso hijo: El proceso hijo realiza el procesamiento de la pebción. El proceso padre pasa a esperar la siguiente pebción. 19

Servidor basado en procesos SERVIDOR P1 P2 HIJO 1 HIJO 2 20

Implementación (1/3) #include "pe,cion.h" #include <stdio.h> #include <,me.h> #include <sys/wait.h> int main() { const int MAX_PETICIONES = 5; int i;,me_t t1,t2; pe,cion_t p; int pid, hijos=0; t1 =,me(null); 21

Implementación (2/3) for (i=0;i<max_peticiones;i++) { recibir_pe,cion(&p); do { fprinw(stderr, "Comprobando hijos\n"); pid = waitpid(- 1, NULL, WNOHANG); if (pid>0) { hijos- - ; } } while (pid > 0); } pid = fork(); if (pid<0) { perror( Error en la creación del hijo"); } if (pid==0) { responder_pe,cion(&p); exit(0); } /* HIJO */ if (pid!=0) { hijos++; } /* PADRE */ 22

Implementación (3/3) } fprinw(stderr, "Comprobando %d hijos\n", hijos); while (hijos>0) { } ; pid = waitpid(- 1, NULL, WNOHANG); if (pid>0) { hijos- - ; } t2 =,me(null); double dif = divime(t2,t1); prinw("tiempo: %lf\n",dif); return 0; 23

Ejecución $ time./ej2 Recibiendo petición Petición 0 recibida después de 0 segundos Comprobando hijos Recibiendo petición Enviando petición 0 Petición 1 recibida después de 3 segundos Comprobando hijos Recibiendo petición Enviando petición 1 Petición 2 recibida después de 3 segundos Comprobando hijos Petición 1 enviada después de 3 segundos Recibiendo petición Enviando petición 2 Petición 3 recibida después de 2 segundos Comprobando hijos Comprobando hijos Recibiendo petición Enviando petición 3 Petición 2 enviada después de 2 segundos Petición 4 recibida después de 4 segundos Comprobando hijos Comprobando hijos Comprobando 3Enviando petición hijos4 Petición 4 enviada después de 0 segundos Petición 0 enviada después de 13 segundos Petición 3 enviada después de 9 segundos Tiempo: 17.000000 real user sys 0m17.311s 0m0.872s 0m3.092s 24

Comparación Normal Procesos Hilo x petición Pool de hilos 54 seg. 17 seg. 25

Problemas Hace falta arrancar un proceso (fork) por cada pebción que llega. Hace falta terminar un proceso (exit) por cada pebción que termina. Excesivo consumo de recursos del sistema. No hay control de admisión. Problemas de calidad de servicio. 26

Soluciones con hilos Hilos bajo demanda. Cada vez que se recibe una pebción se crea un hilo. Pool de hilos. Se Bene un número fijo de hilos creados. Cada vez que se recibe una pebción se busca un hilo libre ya creado para que abenda la pebción. Comunicación mediante una cola de pebciones. 27

Contenido Servidores de pebciones. Solución basada en procesos. Solución basada en hilos bajo demanda. Solución basada en pool de hilos. 28

Hilos bajo demanda Se Bene un hilo receptor encargado de recibir las pebciones. Cada vez que llega una pebción se crea un hilo y se le pasa una copia la pebción al hilo recién creado. Tiene que ser una copia de la pebción porque la pebción original se podría modificar. 29

Implementación #include "pe,cion.h" #include <stdio.h> #include <,me.h> #include <pthread.h> #include <semaphore.h> sem_t snhijos; int main() {,me_t t1, t2; double dif; pthread_t thr; } t1 =,me(null); sem_init(&snhijos, 0, 0); pthread_create(&thr, NULL, receptor, NULL); pthread_join(thr, NULL); sem_destroy(&snhijos); t2 =,me(null); dif = divime(t2,t1); prinw("tiempo: %lf\n",dif); return 0; 30

Implementación: receptor void * receptor (void * param) { const int MAX_PETICIONES = 5; int nservicio = 0; int i; pe,cion_t p; pthread_t th_hijo; for (i=0;i<max_peticiones;i++) { recibir_pe,cion(&p); nservicio++; pthread_create(&th_hijo, NULL, servicio, &p); } } for (i=0;i<nservicio;i++) { fprinw(stderr, "Haciendo wait\n"); sem_wait(&snhijos); fprinw(stderr, "Saliendo de wait\n"); } pthread_exit(0); return NULL; 31

Implementación: servicio void * servicio (void * p) { pe,cion_t pet; copia_pe,cion(&pet,(pe,cion_t*)p); fprinw(stderr, "Iniciando servicio\n"); responder_pe,cion(&pet); sem_post(&snhijos); } fprinw(stderr, "Terminando servicio\n"); pthread_exit(0); return NULL; 32

Reflexión Puede darse una condición de carrera? 33

Ejecución $ time./ej3 Recibiendo petición Petición 0 recibida después de 0 segundos Recibiendo petición Iniciando servicio Enviando petición 1 Petición 1 enviada después de 0 segundos Terminando servicio Petición 1 recibida después de 3 segundos Recibiendo petición Iniciando servicio Enviando petición 2 Petición 2 enviada después de 0 segundos Terminando servicio Petición 2 recibida después de 3 segundos Recibiendo petición Iniciando servicio Enviando petición 3 Petición 3 enviada después de 0 segundos Terminando servicio Petición 3 recibida después de 2 segundos Recibiendo petición Iniciando servicio Enviando petición 4 Petición 4 enviada después de 0 segundos Terminando servicio Petición 4 recibida después de 4 segundos 34

Ejecución Haciendo wait Iniciando servicio Saliendo de wait Enviando petición 4 Haciendo wait Saliendo de wait Haciendo wait Saliendo de wait Haciendo wait Saliendo de wait Haciendo wait Petición 4 enviada después de 0 segundos Terminando servicio Saliendo de wait Tiempo: 12.000000 real user sys 0m12.132s 0m0.046s 0m0.015s 35

Comparación Normal Procesos Hilo x petición Pool de hilos 54 seg. 17 seg. 12 seg. 36

Problema La creación y terminación de hilos Bene un coste menor que la de procesos, pero sigue siendo un coste. No hay control de admisión: Que pasa si llegan muchas pebciones o las pebciones recibidas no terminan? 37

Reflexión Puede darse una condición de carrera? Si se sabe No se sabe 38

Reflexión Puede darse una condición de carrera? pe,cion_t p; recibir_pe,cion(&p); nservicio++; pthread_create(&hijo, NULL, servicio, &p); recibir_pe,cion(&p); nservicio++; pthread_create(&hijo, NULL, servicio, &p);... void * receptor (void * param) 39

Reflexión Puede darse una condición de carrera? pe,cion_t p; recibir_pe,cion(&p); nservicio++; pthread_create(&hijo, NULL, servicio, &p); recibir_pe,cion(&p); nservicio++; pthread_create(&hijo, NULL, servicio, &p);... void * receptor (void * param) 40

Reflexión Puede darse una condición de carrera? void * receptor (void * param) pe,cion_t p; 2 recibir_pe,cion(&p); nservicio++; pthread_create(&hijo, NULL, servicio, &p); recibir_pe,cion(&p); nservicio++; pthread_create(&hijo, NULL, servicio, &p);... 41

Reflexión Puede darse una condición de carrera? void * receptor (void * param) pe,cion_t p; 2 recibir_pe,cion(&p); nservicio++; pthread_create(&hijo, NULL, servicio, &p); recibir_pe,cion(&p); nservicio++; pthread_create(&hijo, NULL, servicio, &p);... 42

Reflexión Puede darse una condición de carrera? void * receptor (void * param) void * servicio (void * p) pe,cion_t p; 2 pe,cion_t pet; recibir_pe,cion(&p); nservicio++; pthread_create(&hijo, NULL, servicio, &p); copia_pe,cion(&pet, p); responder_pe,cion(&pet); recibir_pe,cion(&p); nservicio++; pthread_create(&hijo, NULL, servicio, &p);... 43

Reflexión Puede darse una condición de carrera? void * receptor (void * param) void * servicio (void * p) pe,cion_t p; 2 pe,cion_t pet; recibir_pe,cion(&p); nservicio++; pthread_create(&hijo, NULL, servicio, &p); copia_pe,cion(&pet, p); responder_pe,cion(&pet); recibir_pe,cion(&p); nservicio++; pthread_create(&hijo, NULL, servicio, &p);... 44

Reflexión Puede darse una condición de carrera? void * receptor (void * param) void * servicio (void * p) pe,cion_t p; 2 pe,cion_t pet; recibir_pe,cion(&p); nservicio++; pthread_create(&hijo, NULL, servicio, &p); copia_pe,cion(&pet, p); responder_pe,cion(&pet); recibir_pe,cion(&p); nservicio++; pthread_create(&hijo, NULL, servicio, &p);... 45

Reflexión Puede darse una condición de carrera? void * receptor (void * param) void * servicio (void * p) pe,cion_t p; 3 pe,cion_t pet; recibir_pe,cion(&p); nservicio++; pthread_create(&hijo, NULL, servicio, &p); copia_pe,cion(&pet, p); responder_pe,cion(&pet); recibir_pe,cion(&p); nservicio++; pthread_create(&hijo, NULL, servicio, &p);... 46

Reflexión Puede darse una condición de carrera? void * receptor (void * param) void * servicio (void * p) pe,cion_t p; 3 pe,cion_t pet; recibir_pe,cion(&p); nservicio++; pthread_create(&hijo, NULL, servicio, &p); copia_pe,cion(&pet, p); responder_pe,cion(&pet); recibir_pe,cion(&p); nservicio++; pthread_create(&hijo, NULL, servicio, &p);... 47

Contenido Servidores de pebciones. Solución basada en procesos. Solución basada en hilos bajo demanda. Solución basada en pool de hilos. 48

Pool de threads Un pool de hilos es un conjunto de hilos que se Bene creados desde el principio para ejecutar un servicio: Cada vez que llega una pebción se pone en una cola de pebciones pendientes. Todos los hilos esperan a que haya alguna pebción en la cola y la rebran para procesarla. 49

Implementación: main (1/3) #include "peticion.h" #include <stdio.h> #include <time.h> #include <pthread.h> #include <semaphore.h> #define MAX_BUFFER 128 pe,cion_t buffer[max_buffer]; int n_elementos; int pos_servicio = 0; pthread_mutex_t mutex; pthread_cond_t no_lleno; pthread_cond_t no_vacio; pthread_mutex_t mfin; int fin=0; 50

Implementación: main (2/3) int main() { time_t t1, t2; double dif; pthread_t thr; pthread_t ths[max_servicio]; const int MAX_SERVICIO = 5; int i; t1 = time(null); pthread_mutex_init(&mutex,null); pthread_cond_init(&no_lleno,null); pthread_cond_init(&no_vacio,null); pthread_mutex_init(&mfin,null); pthread_create(&thr, NULL, receptor, NULL); for (i=0;i<max_servicio;i++) { pthread_create(&ths[i], NULL, servicio, NULL); } 51

Implementación: main (3/3) pthread_join(thr, NULL); for (i=0;i<max_servicio;i++) { pthread_join(ths[i],null); } pthread_mutex_destroy(&mutex); pthread_cond_destroy(&no_lleno); pthread_cond_destroy(&no_vacio); pthread_mutex_destroy(&mfin); t2 = time(null); dif = difftime(t2,t1); printf("tiempo: %lf\n",dif); } return 0; 52

Implementación: receptor (1/2) void * receptor (void * param) { const int MAX_PETICIONES = 5; pe,cion_t p; int i, pos=0; for (i=0;i<max_peticiones;i++) { recibir_pe,cion(&p); pthread_mutex_lock(&mutex); while (n_elementos == MAX_BUFFER) pthread_cond_wait(&no_lleno, &mutex); buffer[pos] = p; pos = (pos+1) % MAX_BUFFER; n_elementos++; pthread_cond_signal(&no_vacio); pthread_mutex_unlock(&mutex); } 53

Implementación: receptor (2/2) fprinw(stderr,"finalizando receptor\n"); pthread_mutex_lock(&mfin); fin=1; pthread_mutex_unlock(&mfin); pthread_mutex_lock(&mutex); pthread_cond_broadcast(&no_vacio); pthread_mutex_unlock(&mutex); fprinw(stderr, "Finalizado receptor\n"); pthread_exit(0); return NULL; } /* receptor */ 54

Implementación: servicio (1/2) void * servicio (void * param) { pe,cion_t p; for (;;) { pthread_mutex_lock(&mutex); while (n_elementos == 0) { if (fin==1) { } fprinw(stderr,"finalizando servicio\n"); pthread_mutex_unlock(&mutex); pthread_exit(0); pthread_cond_wait(&no_vacio, &mutex); } // while 55

Implementación: servicio (2/2) } fprinw(stderr, "Sirviendo posicion %d\n", pos_servicio); p = buffer[pos_servicio]; pos_servicio = (pos_servicio + 1) % MAX_BUFFER; n_elementos - - ; pthread_cond_signal(&no_lleno); pthread_mutex_unlock(&mutex); responder_pe,cion(&p); } pthread_exit(0); return NULL; 56

Comparación Normal Procesos Hilo x petición Pool de hilos 54 seg. 17 seg. 12 seg.? 57

SISTEMAS OPERATIVOS: Lección 8: Desarrollo de servidores concurrentes 58