PROGRAMACIÓN CONCURRENTE EN LENGUAJES FUNCIONALES: CONCURRENT HASKELL Rafael Álvarez López Fernando Ávila Ferrer.

Slides:



Advertisements
Presentaciones similares
Tabla de Contenido Concurrencia.
Advertisements

Arquitectura de Sistema de E/S
Introducción Características de la nueva API E/S antes de Java 1.4 ¿Por qué NIO? E/S orientada a bloques El patrón Reactor Canales y Buffers Lectura y.
UNIX COMP 240.
III - Gestión de memoria
I.T.E.S.R.C. Romina Tamez Andrea Martínez Ma. De Lourdes Solís
LÓGICA DE PROGRAMACIÓN
Arquitectura Orientada a Servicios (SOA)
Daniel Morillo Jorge Boscán Gregory Carrasco
Resolución de Problemas y Algoritmos Buffer - Read & Readln
Funciones. Programación, Algoritmos y Estructuras de Datos.
Concepto de programa. Directorio Concepto de programa. Analisis del problema. Resolucion del problema. Desarroollo de un programa. Partes constitutivas.
ALGORÍTMICA Dpto. Ingeniería de Sistemas y Automática
Algoritmos Aleatorizados
Teoría de lenguajes y compiladores
SISTEMAS OPERATIVOS UNIDAD 1..
Johanna Lizeth Rodríguez Lorena Fda. Chávarro Ramos
Ejemplo: Creación y mutación de procesos
Lic. Rosemary Torrico Bascopé
En Java las estructuras de repetición son las mismas que en C/C++.
VHDL.
Introducción a los SSOO Sebastián Sánchez Prieto.
TRADUCTOR DE UN PROGRAMA
Ingeniero Anyelo Quintero
Semana 5 Subprogramas..
Computadoras analógicas Miden magnitudes físicas que se distribuyen en escala continua como pueden ser la temperatura y la presión. Este tipo de computadoras.
Sincronización de Procesos Semáforos Emely Arráiz Ene-Mar 08.
Administración de Archivos
Unidad III Administración de procesos
Actividad 6. Requisitos del software, referente a la estructura y base de datos. M.C. Juan Carlos Olivares Rojas Syllabus May,
Archivos.

Estructura de Datos y Algoritmos
1.1 Concepto y terminología
Streams. / En casi todo programa se necesita traer o enviar información a una fuente externa. / Dicha información puede estar en un archivo en el disco.
Tema 10.3: Asignación de Espacio No Contiguo. Tema 10.3: 2 Silberschatz, Galvin and Gagne ©2005 Fundamentos de los Computadores (ITT, Sist. Electr.),
Material de apoyo Unidad 4 Estructura de datos
XQuery. 2 Introducción De acuerdo al incremento en la cantidad de información que es almacenada, intercambiada y presentada usando XML, la habilidad para.
Desarrollo de aplicaciones para ambientes distribuidos
Hilos En La Computación. (THREADS).
Características de un sistema operativo
5. Sistemas de archivos avanzados1 Tema 5: Sistemas de Archivos Avanzados Resumen: –Sistema de archivos distribuido –File Replication Service.
 El acceso concurrente a datos compartidos puede dar pie a inconsistencia de datos  Mantener la consistencia de los datos requiere mecanismos para asegurar.
Tipos de Datos. Entrada-Salida.. La entrada-salida (I/O) le permite a un programa comunicarse con el mundo exterior. Esta comunicación puede realizarse.
Monitores Mecanismo sincronización de nivel más alto que semáforos Construcción a nivel de lenguaje de programación que controla el acceso a datos compartidos.
Sincronización de Procesos
Teoría de Sistemas Operativos Sincronización Procesos Departamento de Electrónica 2º Semestre, 2003 Gabriel Astudillo Muñoz
Una introducción a la computación evolutiva
Introducción a la tecnología Realizado por: Miguel Ángel Arias.
CONCEPTOS FUNDAMENTALES DEL NIVEL DEL SISTEMA OPERATIVO
Teoría de Sistemas Operativos Departamento de Electrónica 2º Semestre, 2002 Gabriel Astudillo Muñoz
INTRODUCCIÓN A LA INGENIERÍA DEL SOFTWARE
UNIDAD 3 C ONCEPTOS DE S ISTEMAS O PERATIVOS. El ordenador es un sistema programable formado por un conjunto de elementos hardware que necesitan instrucciones.
Unidad 2 – Gestión de Procesos
Introducción a UML Departamento de Informática Universidad de Rancagua
File Transfer Protocol.
PRINCIPIOS DE PROGRAMACIÓN
2008 Escuela de Informática y Telecomunicaciones, DuocUC Escuela de Informática y Telecomunicaciones Clase 9: Funciones, variables y arreglos en BASH Nombre.
LOGO CPU. COMPANY LOGO DEFINICIÓNHISTORIA CPU DE TRANSISTORE S Y DE CIRCUITOS INTEGRADOS DISCRETOS MICROPROCES ADORES OPERACIÓN DEL CPU.
Transacciones seguras  Concurrencia Ing. Yeberth Martinez Programación II.
Lic. Carla Aguirre Montalvo
MIA - Grupo 5 Unidad 2.
Metodología de Programación Ayudantía 4 lelagos.ublog.cl 2009.
Para aplicaciones.   Una variable es un espacio de memoria en donde se almacenan datos 1. VARIABLES.
 Las funciones son un conjunto de instrucciones que realizan una tarea específica. En general toman unos valores de entrada, llamados parámetros y proporcionan.
MEMORIA DINÁMICA.
TIPOS DE SISTEMAS OPERATIVOS.  Que es un sistema operativo??  Es el encargado de brindar al usuario una forma amigable y sencilla de operar, interpretar,
La programación modular es un paradigma de programación que consiste en dividir un programa en módulos o subprogramas con el fin de hacerlo más legible.
Omar Herrera Caamal Rigoberto Lizárraga Luis Cetina Luna.
LE, EI, Profesor Ramón Castro Liceaga UNIVERSIDAD LATINA (UNILA) IV. IMPLANTACION DE ALGORITMOS.
Transcripción de la presentación:

PROGRAMACIÓN CONCURRENTE EN LENGUAJES FUNCIONALES: CONCURRENT HASKELL Rafael Álvarez López Fernando Ávila Ferrer

2 ÍNDICE 1. INTRODUCCIÓN 1.1 Motivación y Orígenes 1.2 Concurrencia y lenguajes funcionales 2. CONCURRENT HASKELL 2.1 Procesos 2.2 Sincronización y comunicación 2.3 Semáforos 2.4 Otras operaciones concurrentes 2.5 Productor/consumidor 2.6 Canales 3. CONCLUSIONES 4. REFERENCIAS

3 1. INTRODUCCIÓN La necesidad de ofrecer concurrencia en el acceso a los recursos computacionales se remonta a los primeros sistemas operativos. Aprovechar al máximo los recursos computacionales fue una necesidad apremiante, sobre todo en la época en que las computadoras eran caras y escasas; el sistema operativo tenía que ofrecer la ejecución concurrente y segura de programas de varios usuarios, que desde distintas terminales utilizaban un solo procesador, y así surgió la necesidad de introducir algunos conceptos de programación concurrente para programar los sistemas operativos.

4 1.1 Motivación y Orígenes Existen sistemas inherentemente concurrentes: los sistemas reactivos. Aparte de esta motivación existen otras dos motivaciones principales, que de hecho fueron anteriores en el tiempo a la utilización de la programación concurrente para la construcción de sistemas reactivos: Explotación de arquitecturas paralelas para obtener ganancia en la velocidad de ejecución (Programación Paralela). Mejorar la utilización del procesador (Sistemas Operativos).

5 1.2 Concurrencia y lenguajes funcionales Debido a la propiedad de confluencia (podemos encontrar dos secuencias de evaluación diferentes que parten del mismo dato de entrada), los lenguajes funcionales pueden utilizar directamente el paralelismo implícito. Otra opción es añadir al lenguaje ciertas extensiones para especificar la concurrencia, como es el caso que vamos a estudiar.

6 2. CONCURRENT HASKELL Concurrent Haskell es una extensión del lenguaje funcional perezoso Haskell para ofrecer la posibilidad de realizar programas concurrentes. Concurrent Haskell representa un nuevo paso que apunta a construir un puente entre el mundo de los lenguajes funcionales puros y los lenguajes intensivos de entrada y salida.

7 Algo más que una extensión de haskell : Consigue integrar la concurrencia en un lenguaje perezoso. Por ejemplo los procesos pueden comunicarse como estructuras de datos sin evaluar unos a otros. Presenta una semántica para Haskell claramente diferenciada en una capa determinista y una capa concurrente. Las técnicas de razonamiento existentes son mantenidas sin modificaciones, por ejemplo, las transformaciones de programas que preservan la corrección en un programa Haskell secuencial también la preservarán en un lenguaje Haskell concurrente. Hay pocas operaciones primitivas nuevas, que son expresivas y fáciles de implementar.

8 nuevos ingredientes a haskell: Procesos, y un mecanismo para gestionarlos. Estados atómicos mutables, para soportar comunicación y cooperación entre los procesos.

9 2.1 Procesos Concurrent Haskell proporciona la nueva primitiva forkIO que inicia un proceso concurrente: forkIO :: IO () -> IO () forkIO a, es una acción que toma a otra acción, a, como su argumento y crea un proceso concurrente que ejecuta dicha acción. La entrada y salida y otros efectos laterales realizados por a, son interpolados de una manera indefinida con aquellos que siguen el forkIO.

10 Ejemplo1: import Control.Concurrent main = forkIO (escribir 'a') >> escribir 'b' where escribir c = putChar c >> escribir c

11 características de forkIO : Como la implementación de haskell usa evaluación perezosa, forkIO necesitará sincronización entre procesos, ya que un proceso puede intentar evaluar un razonamiento que ya está siendo evaluado por otro proceso, en cuyo caso el primero debe ser bloqueado hasta que el último complete la evaluación y sobrescriba el razonamiento con su valor. Como tanto el proceso padre como el hijo, pueden cambiar el mismo estado compartido forkIO introduce inmediatamente el no determinismo. El problema es que casi todas las aplicaciones concurrentes interesantes implican el uso del mismo estado compartido por varios procesos. Por tanto, la solución correcta será proveer mecanismos que permitan la gestión segura de un estado compartido. forkIO es asimétrico. Cuando un proceso ejecuta un forkIO crea un proceso hijo que se ejecuta concurrentemente al padre.

Sincronización y comunicación Los procesos pueden necesitar acceso exclusivo a algunos objetos como por ejemplo ficheros. La manera de implementar este acceso exclusivo requiere una variable compartida mutable o un semáforo. Para que un proceso pueda leer una cadena de valores producida por varios procesos es proporcionando una operación no determinista de ordenación.

13 Type MVar a Un valor del tipo MVar t, para algún tipo t, es el nombre de una posición de memoria que pueda estar vacía o contener un valor de tipo t. A su vez sobre MVar se pueden realizar las siguientes operaciones: newMVar :: IO (MVar a) Crea una nueva MVar takeMVar :: MVar a -> IO a Bloquea hasta que la posición sea no vacía. Entonces lee y devuelve el valor dejando la posición vacía. putMVar :: MVar a -> a -> IO () Escribe un valor en la posición especificada. Si existen uno o mas procesos bloqueados en takeMVar sobre dicha variable, se selecciona uno para que lo procese. Puede producir error utilizarlo sobre una variable que ya contenga un valor.

14 MVar El tipo MVar puede ser usado de tres maneras diferentes: Puede ser usado como una versión sncronizada del tipo MutVar. Puede ser empleado como un tipo de canal, donde takeMVar y PutMVar funcionan como recibir y enviar. El MVar puede ser usado como un semáforo binario, donde los signal y los waits son implementados con putMVar y takeMVar respectivamente.

Semáforos Aunque se puede implementar con un MVar usando las operaciones putMVar y takeMVar, los semáforos tambien están implementados en Concurrent Haskell. Semáforo binario: data QSem newQSem :: Int -> IO QSem waitQSem :: QSem -> IO () signalQSem :: QSem -> IO ()

Semáforos Semáforos de cantidad general: data QSemN newQSemN :: Int -> IO QSemN waitQSemN :: QSemN -> Int -> IO () signalQSemN :: QSemN -> Int -> IO ()

Otras operaciones concurrentes forkIO :: IO a -> IO --Crea proceso hijo threadDelay :: Int -> IO () – Dormir durante n microsegundos newEmptyMVar :: IO (MVar a) – Crear Mvar vacío newMVar :: a -> IO (MVar a) – Inicializar MVAr takeMVar :: MVar a -> IO a – take bloqueante putMVar :: MVar a -> a -> IO () – put bloqueante tryTakeMVar :: MVar a -> IO (Maybe a) – take no bloqueante tryPutMVar :: MVar a -> a -> IO Bool – put no bloqueante isEmptyMVar :: MVar a -> IO Bool -- Test de Mvar vacío swapMVar :: MVar a -> a -> IO a --- Intercambia el valor de Mvar

Productor/consumidor MVar puede ser usado para implementar una conexión entre productor y consumidor. El productor guarda elementos en el MVar y el consumidor los saca. El problema es que no hay nada que impida que el productor escriba un segundo valor antes de que el consumidor haya sacado el primero. Este problema se soluciona con un segundo MVar para manejar confirmaciones entre consumidor y productor. Llamaremos a la abstracción resultante CVar (variable de canal).

19 Productor consumidor type CVar a = (MVar a, -- Productor-> consumidor MVar ()) -- Consumidor -> productor newCVar :: IO (CVar a) newCVar = newMVar >>= \ data_var -> newMVar >>= \ ack_var -> putMVar ack_var ()>> return (data_var, ack_var) putCVar :: CVar a -> a -> IO () putCVar (data_var,ack_var) val= takeMVar ack_var >> putMVar data_var val getCVar :: CVar a -> IO a getCVar (data_var,ack_var) = takeMVar data_var >>= \ val -> putMVar ack_var () >> return val

Canales El proceso creado por el forkIO y su padre pueden realizar entrada y salida independientemente. Podemos pensar en el estado del sistema como un objeto conmutable compartido. Por ejemplo, si dos procesos escriben en el mismo fichero pueden aparecer situaciones indeseadas. Pero como ya sabemos, es común que dos o más procesos quieran acceder al mismo fichero.

21 Canales Usando MVar’s podemos definir un nuevo tipo que llamaremos canal que permitirá que múltiples procesos escriban y lean de él de forma segura. type Channel a = (MVar (Stream a), -- Último leído MVar (Stream a)) -- Último escrito newChan :: IO (Channel a) putChan :: Channel a -> a -> IO getChan :: Channel a -> IO a

22 Canales

23 El canal está implementado por un par de MVar’s que apuntan al último elemento leído (read end) y al último elemento escrito (write end) del canal respectivamente. Las Mvar del canal proporcionan un mecanismo mediante el cual las operaciones de put y get pueden modificar el read end y el write end del canal. Los datos en el buffer son almacenados en un Stream que es un MVar que puede estar vacío (en cuyo caso no hay datos en el stream) o almacena un Item.

24 type Stream a = MVar (Item a) Un Item es simplemente un par de elementos, uno con el dato y otro apundanto al resto del stream. data Item a = MkItem a (Stream a) Un Stream puede ser considerado como una lista que consiste en alternar Items y Mvars que termina con un “agujero” que consiste en un MVar vacío. El Write end del canal apunta a dicho “agujero”(Hole).

25 newChan = do { read <- newEmptyMVar ; write <- newEmptyMVar ; hole <- newEmptyMVar ; putMVar read hole ; putMVar write hole ; return (read,write) }

26 putChan (read,write) val = do { new_hole <- newEmptyMVar ; old_hole <- takeMVar write ; putMVar write new_hole ; putMVar old_hole (MkItem val new_hole) }

27 getChan (read,write) = do { head_var <- takeMVar read ; MkItem val new_head <- takeMVar head_var ; putMVar read new_head ; return val }

28 canal multicast dupChan :: Channel a -> IO (Channel a) dupChan (read,write) = do { new_read <- newEmptyMVar ; hole <- readMVar write ; putMVar new_read hole ; return (new_read, write) }

29 Implementación de canales en Concurrent Haskell data Chan a newChan :: IO (Chan a) -- Nuevo canal writeChan :: Chan a -> a -> IO () --Escribe dato en canal readChan :: Chan a -> IO a --Lee un dato del canal dupChan :: Chan a -> IO (Chan a) --Duplica el canal unGetChan :: Chan a -> a -> IO () --Devuelve un dato al canal isEmptyChan :: Chan a -> IO Bool --Comprueba si está vacío getChanContents :: Chan a -> IO [a] -- lee todo el contenido writeList2Chan :: Chan a -> [a] -> IO () -- Escribe el contenido de una lista en el canal

30 3. CONCLUSIONES Hemos comprobado como Concurrent Haskell aporta nueva funcionalidad a Haskell. Añadiendo forkIO y MVars a Haskell damos un salto cualitativo en cuanto a la cantidad de aplicaciones que podemos escribir. Las extensiones son sencillas y simples de describir. En la actualidad Haskell y sus versiones concurrentes están siendo empleados de manera comercial como herramienta de programación para servidores, aportando una nueva manera de programar potente y elegante.

31 4. REFERENCIAS Ruíz, B.C.; Gutiérrez, F.; Guerrero, P.; Gallardo, J.E.: Razonando con Haskell. Una introducción a la Programación Funcional. Servicio reprogr. (OCÉ) E.T.S.I.I., Universidad de Málaga rrent.html Tackling the Awkward Squad: monadic input/output, concurrency, exceptions, and foreign-language calls in Haskell Simon PEYTON JONES Microsoft Research, Cambridge Concurrent Haskell Simon Peyton Jones (University of Glasgow) Andrew Gordon (University of Cambridge) Sigbjorn Finne (University of Glasgow) Notas para la asignatura Programación Declarativa Avanzada. Blas Carlos Ruiz Jiménez