PROGRAMACI - PowerPoint PPT Presentation

About This Presentation
Title:

PROGRAMACI

Description:

La necesidad de ofrecer concurrencia en el acceso a los recursos computacionales ... vac a o contener un valor de tipo t. A su vez sobre MVar se pueden realizar las ... – PowerPoint PPT presentation

Number of Views:90
Avg rating:3.0/5.0
Slides: 32
Provided by: gigg
Category:

less

Transcript and Presenter's Notes

Title: PROGRAMACI


1
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 () -gt 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') gtgt escribir 'b'
  • where escribir c putChar c gtgt 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.

12
2.2 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 -gt 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 -gt a -gt 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.

15
2.3 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 -gt IO QSem
  • waitQSem QSem -gt IO ()
  • signalQSem QSem -gt IO ()

16
2.3 Semáforos
  • Semáforos de cantidad general
  • data QSemN
  • newQSemN Int -gt IO QSemN
  • waitQSemN QSemN -gt Int -gt IO ()
  • signalQSemN QSemN -gt Int -gt IO ()

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

18
2.5 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-gt consumidor
  • MVar ()) -- Consumidor -gt productor
  • newCVar IO (CVar a)
  • newCVar newMVar gtgt \ data_var -gt
  • newMVar gtgt \ ack_var -gt
  • putMVar ack_var () gtgt return (data_var,
    ack_var)
  • putCVar CVar a -gt a -gt IO ()
  • putCVar (data_var,ack_var) val takeMVar ack_var
    gtgt putMVar data_var val
  • getCVar CVar a -gt IO a
  • getCVar (data_var,ack_var) takeMVar data_var
    gtgt \ val -gt
  • putMVar ack_var () gtgt return val

20
2.6 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 MVars 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 -gt a -gt IO
  • getChan Channel a -gt IO a

22
Canales
23
  • El canal está implementado por un par de MVars
    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 lt- newEmptyMVar
  • write lt- newEmptyMVar
  • hole lt- newEmptyMVar
  • putMVar read hole
  • putMVar write hole
  • return (read,write)

26
  • putChan (read,write) val
  • do new_hole lt- newEmptyMVar
  • old_hole lt- takeMVar write
  • putMVar write new_hole
  • putMVar old_hole (MkItem val new_hole)

27
  • getChan (read,write)
  • do head_var lt- takeMVar read
  • MkItem val new_head lt- takeMVar head_var
  • putMVar read new_head
  • return val

28
canal multicast
  • dupChan Channel a -gt IO (Channel a)
  • dupChan (read,write)
  • do new_read lt- newEmptyMVar
  • hole lt- 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 -gt a -gt IO () --Escribe
    dato en canal
  • readChan Chan a -gt IO a --Lee un dato del
    canal
  • dupChan Chan a -gt IO (Chan a) --Duplica el
    canal
  • unGetChan Chan a -gt a -gt IO () --Devuelve
    un dato al canal
  • isEmptyChan Chan a -gt IO Bool --Comprueba
    si está vacío
  • getChanContents Chan a -gt IO a -- lee
    todo el contenido
  • writeList2Chan Chan a -gt a -gt 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
  • http//www.haskell.org
  • 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. 2000
  • http//www.haskell.org/ghc/docs/latest/html/librar
    ies/base/Control.Concurrent.html
  • Tackling the Awkward Squad monadic input/output,
    concurrency, exceptions, and foreign-language
    calls in Haskell
  • Simon PEYTON JONES Microsoft Research, Cambridge
    simonpj_at_microsoft.com
  • http//research.microsoft.com/users/simonpj
  • 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
Write a Comment
User Comments (0)
About PowerShow.com