Una vista panorámica de la situación actual de la concurrencia y la asincronía. Comparando modelos de concurrencia y técnicas de programación asíncrona en lenguajes de programación como Java, C/C++ y JavaScript.
4. 4
Introducción a la Programación Concurrente
•¿Qué es la programación concurrente?
•¿Dónde se usa la programación concurrente?
•¿Para qué se usa la programación concurrente?
•¿Cómo se programa concurrentemente?
•Conclusiones
Programación Concurrente
5. 5
¿Qué es la programación concurrente?
• La programación concurrente se ocupa del estudio y
desarrollo de programas que puedan realizar varias
tareas “al mismo tiempo”
• La disciplina surge en los años 60 cuando los sistemas
operativos, gracias a mejoras hardware, comienzan a
aprovechar el procesador ejecutando varios procesos de
forma concurrente:
Ofrecer un entorno interactivo a múltiples usuarios
Aprovechar el procesador cuando un proceso espera por una
operación de entrada/salida
Introducción a la Programación Concurrente
6. 6
¿Qué es la programación concurrente?
• Ejecución de varios programas a la vez en ordenadores
personales (multitarea)
MS-DOS no permitía la ejecución de varios programas de
forma concurrente
Windows 1.0 (1985) permitió la ejecución de varios
programas a la vez pero de forma poco robusta
(mutitarea cooperativa)
Windows NT 3.1 (1993) ofrece la primera ejecución
simultánea de programas de forma segura (multitarea
preferente o preemtive)
Linux (1991) permite la ejecución simultánea de varios
programas (comoWinNT) y el acceso de varios usuarios
• Actualmente la gran mayoría de dispositivos de computación
permiten la ejecución de procesos concurrentes
Introducción a la Programación Concurrente
7. 7
¿Qué es la programación concurrente?
• Inicialmente la concurrencia sólo la usaba el sistema
operativo para la ejecución de varios programas de forma
simultánea, pero internamente los programas no podían
realizar varias tareas concurrentemente
• Los lenguajes de programación y sus librerías evolucionaron
para que los desarrolladores pudieran implementar programas
concurrentes (que realizan varias tareas simultáneamente)
• Algunos lenguajes de programación permiten el desarrollo de
programas concurrentes (casi todos los usados en la
actualidad…)
C/C++, Java, JavaScript, Scala, Go, C#, Haskell, Erlang, OCAM…
Introducción a la Programación Concurrente
8. 8
Programa Secuencial y Proceso
•Procesos
Cada proceso tiene su propio espacio de
memoria y su propia pila de ejecución
(stack)
Los procesos se pueden comunicar entre sí,
pero son unidades autónomas e
independientes (un fallo en un proceso no
afecta a los demás procesos).
Están gestionados por el sistema operativo.
¿Qué es la programación concurrente?
9. 9
Programa Secuencial y Proceso
¿Qué es la programación concurrente?
Programa
Secuencial
Proceso
Existen dos procesos
concurrentes del programa
“eclipse.exe”
Administrador de tareas de Windows XP
11. 11
Programa Secuencial y Proceso
•Programas concurrentes implementados con
procesos del sistema operativo
Los primeros programas concurrentes estaban
formados por varios procesos colaborando entre sí
En linux es habitual que los procesos se comuniquen
usando pipes (tuberías)
Se consideró que no era tan importante que los
procesos fueran independientes, se prefería que
consumieran menos recursos, que fuera más ligeros
Además, ciertas aplicaciones necesitaban compartir la
memoria para colaborar más estrechamente entre sí
¿Qué es la programación concurrente?
12. 12
Programa Secuencial y Proceso
•Hilos (Threads)
Para el desarrollo de programas concurrentes se
diseñaron unos procesos ligeros llamados hilos
(threads)
Todos los threads de un programa se ejecutan en el
mismo espacio de memoria (comparten toda la
memoria)
Cada thread tiene su propia pila de ejecución
(stack)
¿Qué es la programación concurrente?
13. 13
Programa Secuencial y Proceso
•Hilos (Threads)
Consumen menos recursos que los procesos
“pesados” del sistema operativo (menos
memoria y menor tiempo de creación)
Son menos robustos que los procesos
pesados, ya que un fallo en un thread afecta
a todo el programa y puede llegar provocar
su finalización inesperada
¿Qué es la programación concurrente?
14. 14
Programa Secuencial y Proceso
• Explorador de
procesos en
Windows con
visualización
de los threads
de cada
proceso
¿Qué es la programación concurrente?
15. 15
Programa Secuencial y Proceso
•Puede darse concurrencia a dos niveles
A nivel de Sistema Operativo
Programa Secuencial: Fichero ejecutable
Proceso: Proceso que aparece en el sistema cuando
se ejecuta un fichero ejecutable
Todos los sistemas operativos actuales permiten la
concurrencia de procesos
¿Qué es la programación concurrente?
16. 16
Programa Secuencial y Proceso
•Puede darse concurrencia a dos niveles
A nivel de Programa
Programa Secuencial: Fragmento de código de un
programa
Proceso: Ejecución independiente de un fragmento
de código
La mayoría de las tecnologías de desarrollo
(lenguajes+librerías) permiten la concurrencia con
hilos
¿Qué es la programación concurrente?
17. 17
Programa Secuencial y Proceso
•¿Qué es mejor: procesos o hilos?
Los procesos consumen más recursos que los hilos
(memoria y CPU)
Los procesos tardan más tiempo en iniciarse que
los hilos
Los procesos son más robustos que los hilos: Si un
proceso falla, el resto de procesos siguen su
ejecución, pero si un hilo falla de forma no
controlada, puede finalizar la ejecución del
programa completo
¿Qué es la programación concurrente?
18. 18
Programa Secuencial y Proceso
• Hilos y procesos en los
navegadores web
Google Chrome: Un proceso por
cada pestaña. Si una pestaña
falla, no afecta a las demás
Mozilla Firefox: Durante mucho
tiempo un único proceso para
todas las pestañas (con varios
hilos de ejecución). Si una pestaña
fallaba, afectaba a todas las
demás. Ahora es similar a chrome
con un proceso por pestaña.
¿Qué es la programación concurrente?
https://wiki.mozilla.org/Electrolysis
19. 19
Programa Secuencial y Proceso
•Fibras
Tanto los procesos como los hilos son gestionados por
el sistema operativo con ayuda del procesador
Los lenguajes concurrentes que usan hilos delegan en
el SO su creación y administración
Aunque los hilos son más ligeros que los procesos,
todavía siguen siendo bastante costosos
Además, su número está limitado a unos 10.000 en un
servidor estándar por el consumo de memoria (aunque
no estén haciendo nada)
¿Qué es la programación concurrente?
20. 20
Programa Secuencial y Proceso
•Fibras
Las fibras son procesos ligeros gestionados
completamente por el lenguaje de programación
(sin soporte del sistema operativo)
Son mucho más ligeras que los hilos:
No tardan prácticamente nada en crearse
Puede haber cientos de miles en un servidor estándar
No son tan genéricas como los hilos y están
diseñadas para ciertos casos específicos
¿Qué es la programación concurrente?
21. 21
Programa Secuencial y Proceso
•Fibras
Se han puesto de moda en los últimos años debido
al lenguaje Go diseñado por Google (en Go las
fibras se llaman gorutinas)
Java no ofrece fibras de forma nativa, pero el
proyecto Loom permitirá que se puedan usar.
Erlang y Haskell usan fibras
¿Qué es la programación concurrente?
https://en.wikipedia.org/wiki/Fiber_(computer_science)
22. 22
Procesos Concurrentes
•Procesos Concurrentes
P1 y P2 se dice que son dos procesos concurrentes si
la primera instrucción de uno de ellos se ejecuta
entre la primera y la última instrucción del otro
¿Qué es la programación concurrente?
P1
P2
Tiempo
23. 23
Programa Concurrente
•Programa Concurrente
Conjunto de varios programas secuenciales, cuyos
procesos pueden ejecutarse concurrentemente en
un sistema informático
También llamado multi-hilo (multi-threaded)
En contraposición, a los programas que no son
concurrentes se les denomina mono-hilo (single-
threaded)
¿Qué es la programación concurrente?
24. 24
Introducción a la Programación Concurrente
•¿Qué es la programación concurrente?
•¿Dónde se usa la programación concurrente?
•¿Para qué se usa la programación concurrente?
•¿Cómo se programa concurrentemente?
•Conclusiones
Programación Concurrente
25. 25
¿Dónde se usa la programación concurrente?
•Arquitecturas de Sistemas Concurrentes
Sistemas monoprocesador
Sistemas multiprocesador
Muy acoplados
Poco acoplados
Sistemas híbridos
Introducción a la Programación Concurrente
26. 26
Arquitecturas Físicas
•Sistemas monoprocesador
Sistemas con un único procesador
La arquitectura de los PCs hace algunos años
¿Dónde se usa la programación concurrente?
Procesador
Memoria Entrada/Salida
Bus
27. 27
•La Ley de Moore
Arquitecturas Físicas
¿Dónde se usa la programación concurrente?
Es una ley empírica que expresa
que aproximadamente cada dos
años se duplica el número de
transistores en un circuito
integrado
Formulada por el cofundador de
Intel, Gordon E. Moore, el 19 de
abril de 1965.
Posteriormente fue adaptada
para indicar que los transistores
se doblarían cada 18 meses
29. 29
•La Ley de Moore: el aumento de velocidad y
la potencia de cómputo
Durante años bastaba con aumentar la frecuencia
de reloj de los chips para aumentar la velocidad de
ejecución y por tanto la potencia de cómputo
Actualmente existen impedimentos físicos para
seguir aumentando la frecuencia de reloj,
principalmente debidos a la potencia consumida y
la disipación del calor
Arquitecturas Físicas
¿Dónde se usa la programación concurrente?
31. 31
•La Ley de Moore: el aumento de velocidad y la
potencia de cómputo
Para aumentar la potencia de cómputo es necesario
incluir varias unidades de proceso o cores en cada
procesador
La tendencia es tener cada vez más cores por
procesador
Arquitecturas Físicas
¿Dónde se usa la programación concurrente?
Free lunch is over!
http://www.gotw.ca/publications/concurrency-ddj.htm
32. 32
Arquitecturas Físicas
• Sistemas multiprocesador muy acoplados
Actualmente se están integrando varios procesadores en un único
chip
A los procesadores internos se les denomina cores o núcleos de
ejecución
Al chip se le denomina procesador multicore
La mayoría de los procesadores actuales en PCs, Smartphones,
tabletas, etc. tienen esta arquitectura
¿Dónde se usa la programación concurrente?
Procesador
Memoria Entrada/Salida
Núcleo Núcleo
Bus
33. 33
Arquitecturas Físicas
•Sistemas multiprocesador muy acoplados
Varios procesadores en la misma máquina
Usado en servidores y estaciones de trabajo
Conocidos como SMP (Symmetric Multi-Processing)
¿Dónde se usa la programación concurrente?
Entrada/Salida
Bus
Memoria
Común
Procesador Núcleo Núcleo Procesador Núcleo Núcleo
35. 35
Arquitecturas Físicas
•Modelos de Concurrencia
Son diferentes enfoques para el desarrollo de
programas concurrentes
Se dividen en dos grandes bloques, en función de
la arquitectura física en la que se pueden usar
Con arquitecturas híbridas, se pueden combinar
varios modelos en un mismo programa
concurrente o usar el mismo modelo
¿Dónde se usa la programación concurrente?
36. 36
Arquitecturas Físicas
•Modelos de Concurrencia
Modelos de memoria compartida
Los procesos pueden acceder a una memoria común
Existen variables compartidas que varios procesos
pueden leer y escribir
Modelos de paso de mensajes
Los procesos se intercambian mensajes entre sí
Un proceso envía mensaje y otro proceso lo recibe
¿Dónde se usa la programación concurrente?
37. 37
Arquitecturas Físicas
¿Dónde se usa la programación concurrente?
Modelos de Concurrencia
Arquitecturas
de Sistemas Concurrentes
Paso de
Mensajes
Memoria
Compartida
Monoprocesador √ √
Multiprocesador √ √
Sistemas distribuidos √ ?*
* Hay librerías que simulan la memoria compartida sobre red
38. 38
Asignación de Procesos a Procesadores
•Un procesador (core) sólo puede ejecutar un
proceso a la vez
•Si hay tantos procesadores como procesos,
cada proceso se ejecuta en un procesador
•Lo más habitual es que haya más procesos que
procesadores
•¿Qué ocurre en ese caso?
¿Dónde se usa la programación concurrente?
39. 39
Asignación de Procesos a Procesadores
•Multiproceso
Cada proceso se ejecuta en su propio procesador en un
sistema de memoria compartida
¿Dónde se usa la programación concurrente?
Procesador1
Entrada/Salida
Procesador3
Memoria
Común
Proc1 Proc2 Proc3
Procesador2
Bus
40. 40
Asignación de Procesos a Procesadores
• Paralelismo Real
Se obtiene cuando hay un
procesador por cada
proceso (Mutiproceso)
Se consigue un aumento
de la velocidad de
ejecución del programa
con respecto a la
ejecución secuencial
¿Dónde se usa la programación concurrente?
Ejecución Secuencial
Proc1
Proc2
t
Paralelismo Real
Proc1
Proc2
t
41. 41
Asignación de Procesos a Procesadores
•Multiprogramación
Varios procesos se ejecutan en el mismo procesador
Cada proceso se ejecuta durante un tiempo y luego pasa a
ejecutarse el siguiente proceso (Compartición de tiempo)
¿Dónde se usa la programación concurrente?
Entrada/SalidaMemoria
Proc2 Proc3
Procesador
Bus
Proc1
42. 42
Asignación de Procesos a Procesadores
• Paralelismo Simulado o
Pseudoparalelismo
Se obtiene cuando varios
procesos comparten el mismo
procesador
(Multiprogramación)
El usuario percibe una
sensación de paralelismo real
Aparentemente no se
consigue un aumento de la
velocidad de ejecución del
programa con respecto a la
ejecución secuencial
¿Dónde se usa la programación concurrente?
Paralelismo Simulado
Proc1
Proc2
Proc1
Proc2
Ejecución Secuencial
t
t
43. 43
Asignación de Procesos a Procesadores
• Paralelismo Simulado o
Pseudoparalelismo
Cuando los procesos esperan
por entrada/salida (IO), el
procesador se puede
aprovechar para otro proceso
En este caso se reduce el
tiempo de ejecución del
conjunto de procesos
Se obtiene una reducción del
tiempo de ejecución incluso
con un procesador
¿Dónde se usa la programación concurrente?
Paralelismo Simulado
Ejecución Secuencial
Proc1
Proc2
Proc1
Proc2
Proceso
Bloqueado
44. 44
Asignación de Procesos a Procesadores
•Asignación de Procesos a Procesadores
¿Dónde se usa la programación concurrente?
Paralelismo Real
Aumenta la velocidad
de ejecución
Paralelismo Simulado
Aumenta la velocidad
de ejecución si los procesos usan
Instrucciones de IO
En un sistema informático lo más habitual es que se use la
Multiprogramación aunque se disponga de varios procesadores, porque
en la mayoría de las ocasiones hay más procesos que procesadores
Cada procesador ejecuta un
proceso
• Multiproceso
Cada procesador ejecuta varios
procesos de forma intercalada
• Multiprogramación
45. 45
Introducción a la Programación Concurrente
•¿Qué es la programación concurrente?
•¿Dónde se usa la programación concurrente?
•¿Para qué se usa la programación concurrente?
•¿Cómo se programa concurrentemente?
•Conclusiones
Programación Concurrente
46. 46
¿Para qué se usa la programación concurrente?
•¿Cuándo usar la concurrencia?
Existen muchas situaciones en las que un programa
concurrente es mejor que uno secuencial
Más fácil de implementar
Más rápido en ejecutarse
Consumirá menos recursos (memoria, CPU…)
En otros casos, es imprescindible que el programa
sea concurrente o no se podrá implementar
Introducción a la Programación Concurrente
47. 47
¿Para qué se usa la programación concurrente?
•¿Cuándo usar concurrencia?
Imprescindible
1) Servidores que atienden varios usuarios / peticiones
simultáneamente
2) Aplicaciones interactivas (que realizan tareas en
segundo plano)
Conveniente
3) Aumentar la velocidad cuando hay entrada y salida con
un único procesador
4) Aumentar la velocidad de los programas usando varios
procesadores en paralelo
Introducción a la Programación Concurrente
48. 48
¿Para qué se usa la programación concurrente?
•1) Servidores que atienden
varios usuarios / peticiones
simultáneamente
ServidorWeb: Atiende a cientos de
peticiones simultáneamente
Servidores deWhatsApp: Atiende
cientos de usuarios conectados
Servidores de juegos on-line:
Múltiples partidas simultáneas
Introducción a la Programación Concurrente
49. 49
•2) Aplicaciones interactivas (que realizan tareas en
segundo plano)
El programa realiza cálculos en segundo plano mientras
que el usuario sigue trabajando
Ejemplos:
Eclipse compila en segundo plano mientras se sigue
editando
Un navegador carga una página web mientras el usuario
navega por otras
¿Para qué se usa la programación concurrente?
Introducción a la Programación Concurrente
50. 50
•3) Aumentar la velocidad cuando hay entrada y
salida en sistemas con un procesador
Algunas aplicaciones que mayoritariamente realizan
operaciones en el procesador pero no realizan
entrada/salida: diseño 3D, algoritmos de optimización,
etc.
En estas aplicaciones, si sólo hay un único procesador,
es más eficiente que el programa sea secuencial
En las aplicaciones que tienen entrada/salida (acceso a
disco, red), es más eficiente que sean concurrentes
incluso con un único procesador)
¿Para qué se usa la programación concurrente?
Introducción a la Programación Concurrente
51. 51
•4) Aumentar la velocidad de los programas usando
varios procesadores en paralelo
Los procesadores ya no van a aumentar de velocidad
Los nuevos procesadores tendrán cada vez más cores
Las aplicaciones tendrán que ser concurrentes
(multithreaded) para aprovechar toda la potencia de
cómputo disponible
A medida que pase el tiempo, cada vez será más crítico
porque habrá más cantidad de cores
¿Para qué se usa la programación concurrente?
Introducción a la Programación Concurrente
52. 52
•4) Aumentar la velocidad de los programas
usando varios procesadores en paralelo
El compilador de java oficial de Oracle es single-
threaded (secuencial) y por tanto no aumenta de
velocidad con varios cores
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=
6629150
El compildor de java incluido en Eclipse es multi-
threaded (concurrente) desde 2008 y por tanto si
aumenta de velocidad con varios cores
https://bugs.eclipse.org/bugs/show_bug.cgi?id=142126
¿Para qué se usa la programación concurrente?
Introducción a la Programación Concurrente
53. 53
•4) Aumentar la velocidad de los programas usando
varios procesadores en paralelo
Comparativa de servidores web con diferentes cores
¿Para qué se usa la programación concurrente?
Introducción a la Programación Concurrente
https://www.rootusers.com/web-server-performance-benchmark/
54. 54
•4) Aumentar la velocidad de los programas usando
varios procesadores en paralelo
Gimp: Puede usar varios procesadores/cores a la vez para
aplicar efectos a una imagen
¿Para qué se usa la programación concurrente?
Introducción a la Programación Concurrente
55. 55
Introducción a la Programación Concurrente
•¿Qué es la programación concurrente?
•¿Dónde se usa la programación concurrente?
•¿Para qué se usa la programación concurrente?
•¿Cómo se programa concurrentemente?
•Conclusiones
Programación Concurrente
56. 56
¿Cómo se programa concurrentemente?
•Existen muchas formas diferentes de
implementar un programa concurrente
•Depende del lenguaje de programación y la
librería que estemos usando
•Existen modelos teóricos que luego se
concretan de formas diferentes en los diferentes
lenguajes y librerías
•Se les conoce como “Modelos de concurrencia”
Introducción a la Programación Concurrente
57. 57
¿Cómo se programa concurrentemente?
•Modelos de Concurrencia
Existen dos grandes familias: Modelo de Memoria
compartida y Modelo de Paso de Mensajes
Hay varios modelos diferentes dentro de cada
familia
No hay un consenso sobre cual es el mejor de todos
(como ocurre con los lenguajes de programación)
Introducción a la Programación Concurrente
58. 58
•Niveles de abstracción de los modelos
Bajo nivel
Cercanos a la funcionalidad ofrecida por el hardware
Alto nivel
Inspirados en modelos matemáticos
Normalmente cualquier modelo de alto nivel se
puede implementar sobre cualquier otro modelo de
más bajo nivel
¿Cómo se programa concurrentemente?
Introducción a la Programación Concurrente
59. 59
•La elección de un modelo u otro está determinado
por:
Tipo de programa a implementar
Las aplicaciones de red pueden tener distintas necesidades que
las aplicaciones interactivas
Lenguaje de programación utilizado y sus librerías
Hay lenguajes en los que sólo se puede usar un modelo de alto
nivel (JavaScript)
Los lenguajes que ofrecen modelos de bajo nivel suelen permitir
algunos de los modelos de alto nivel con librerías (Java)
Arquitectura física
Los sistemas multiprocesador poco acoplados no pueden usar
modelos de memoria compartida (pero al contrario si)
¿Cómo se programa concurrentemente?
Introducción a la Programación Concurrente
60. 60
•Modelos de concurrencia más usados
Hilos y cerrojos
Actores
Comunicando procesos secuenciales (CSP)
Programación Funcional
Memoria software transaccional (STM)
… (hay más)
¿Cómo se programa concurrentemente?
Introducción a la Programación Concurrente
61. 61
•Hilos y cerrojos
Modelo de memoria compartida
Es el modelo de más bajo nivel, el más cercano a las
primitivas ofrecidas por el hardware
Suele estar disponible en lenguajes imperativos
(estructurados y orientados a objetos)
Es el modelo más usado y más potente, pero
también el más complejo de programar
Modelos de concurrencia
¿Cómo se programa concurrentemente?
Lenguajes: C/C++, Java, Ruby, Python, C#...
62. 62
•Hilos y cerrojos
Se le conoce con muchos nombres en la literatura:
Estado mutable compartido
Memoria compartida protegida por cerrojos (locks)
Programación con hilos
Programación basada en cerrojos
Aunque hay más modelos de memoria compartida,
como es el más usado, hay veces que se le llama
directamente como Memoria compartida
Modelos de concurrencia
¿Cómo se programa concurrentemente?
63. 63
•Actores
Modelo de paso de mensajes
Esta definido por un modelo matemático
Los actores son las primitivas concurrentes de procesamiento que
se comunican enviando mensajes a otros actores
Dependiendo del mensaje que reciba, un actor puede:
Crear más actores,
Enviar más mensajes
Cambiar su estado
Lenguajes: Erlang, Occam, Oz, Scala, …
Librerías: Akka (Java), Quasar (Java), Actor-CPP (C++)…
Modelos de concurrencia
¿Cómo se programa concurrentemente?
64. 64
•Comunicando procesos secuenciales (CSP)
Modelo de paso de mensajes
Es un lenguaje formal basado en el algebra o cálculo de
procesos
Los procesos se comunican enviándose mensajes a través de
canales
El envío de mensajes es parecido al modelo de actores, pero
en CSP un proceso puede tener varios canales pero en el
modelo de actores sólo uno (de recepción)
Lenguajes: Go, Occam …
Librerías: Quasar (Java), JCSP (Java), C++CSP2 (C++)
Modelos de concurrencia
¿Cómo se programa concurrentemente?
65. 65
•Programación Funcional
Modelo de memoria compartida
Está basado en que en la programación funcional la información
no se modifica (es inmutable), por eso se puede compartir entre
varios hilos sin problemas
Todo el procesamiento se hace en base a funciones que generan
valores de salida partiendo de los parámetros de entrada
Como un programa está descrito de forma declarativa como una
composición de funciones, es paralelizarble
Lenguajes: Parallel Haskell…
Librerías: Streams de Java 8 …
Modelos de concurrencia
¿Cómo se programa concurrentemente?
66. 66
•Memoria software transaccional (STM)
Modelo de memoria compartida
Aplica el concepto de transacciones de bases de datos a la
memoria compartida entre procesos
Dentro de una transacción un proceso puede leer y escribir
la memoria compartida.Todas las lecturas y escrituras
ocurren de forma atómica, y otros procesos no pueden ver
estados intermedios.
Lenguajes: Clojure, Haskell…
Librerías: Multiverse (Java), Durus (Python), TinySTM (C/C++)…
Modelos de concurrencia
¿Cómo se programa concurrentemente?
67. 67
Familia Modelo Lenguajes Librerías
Modelo de
Memoria
compartida
Hilos y Cerrojos C/C++, Java,
Ruby, Python,
C#, Scala, …
Memoria
Software
Transaccional
(STM)
Clojure,
Haskell…
Multiverse (Java), Durus
(Python), TinySTM (C/C++)…
Programación
funcional
Parallel
Haskell…
Streams en Java 8
Modelo de
Paso de
mensajes
Actores Erlang, Occam,
Oz, Scala, …
Akka (Java), Quasar (Java),
Actor-CPP (C++)…
CSP Go, Occam … JCSP (Java), Quasar (Java), C+
+CSP2 (C++)
Modelos de concurrencia
¿Cómo se programa concurrentemente?
69. 69
Conclusiones
•Concurrencia vs Paralelismo
Concurrencia
En general se puede considerar que la concurrencia o la
programación concurrente se refieren a técnicas de
elaboración de programas con varios flujos de ejecución
Paralelismo
El paralelismo o ejecución en paralelo se utiliza para
hablar de un tipo de ejecución de un programa
concurrente sobre varios procesadores con procesos
ejecutándose de forma simultánea
Introducción a la Programación Concurrente
The Art of Concurrency. 2009. Clay Breshears. O’REALLY
70. 70
Conclusiones
•Concurrencia vs Paralelismo
Sistema concurrente
Se dice que un sistema es concurrente si permite que
dos o más acciones estén en progreso al mismo
tiempo
Sistema paralelo
Se dice que un sistema es paralelo si permite que dos
o más acciones se ejecuten de forma simultánea
Un sistema paralelo necesita al menos dos
procesadores
El paralelismo es un tipo de concurrencia
Introducción a la Programación Concurrente
The Art of Concurrency. 2009. Clay Breshears. O’REALLY
71. 71
Conclusiones
•Concurrencia vs Paralelismo
Existen muchos casos en los que el concepto de paralelismo se
utiliza en el sentido de concurrente
Paralelización
Se denomina paralelización al proceso de convertir programas
secuenciales en programas concurrentes, generalmente con el
objetivo de ejecutarse de forma paralela para aprovechar la
potencia de cómputo
Programación paralela
En los últimos 20 años, el término programación paralela se ha
usado para referiste a la programación de sistemas de memoria
distribuida (en red) porque son sistemas paralelos
Introducción a la Programación Concurrente
The Art of Concurrency. 2009. Clay Breshears. O’REALLY
74. 74
Concurrencia en Java
•Java es una plataforma de desarrollo formada
por
Lenguaje de programación Java
Máquina virtual de Java (JVM)
Librería estándar (API)
•La máquina virtual y la librería estándar ofrece
portabilidad en sistemas operativos y
plataformas hardware
Concurrencia en los Lenguajes de Programación
75. 75
Concurrencia en Java
•Modelo de concurrencia
Java ofrece un modelo de concurrencia de memoria
compartida integrado en el lenguaje Java y en la
librería estándar
El soporte de concurrencia ha evolucionado mucho
en Java a lo largo del tiempo
En las últimas versiones aparecen herramientas de
alto nivel en la librería estándar que permiten al
desarrollador abstraerse de detalles de bajo nivel
Concurrencia en los Lenguajes de Programación
76. 76
Concurrencia en Java
•La concurrencia también está integrada en el
propio lenguaje de programación
Está definido cómo se comparte la memoria entre
diferentes hilos en el Modelo de Memoria de Java
[1] (Java Memory Model)
Existen palabras reservadas en el propio lenguaje
para delimitar zonas bajo exclusión mutua
(synchronized) y para especificar que un atributo es
compartido entre hilos (volatile)
Concurrencia en los Lenguajes de Programación
[1] http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html
77. 77
Concurrencia en Java
•Soporte en la librería estándar
Como Java es un lenguaje orientado a objetos, los
hilos se representan como objetos de la clase
java.lang.Thread
Esta clase tiene métodos para controlar el ciclo de
vida del hilo (configurar su nombre, prioridad, iniciar,
esperar a que finalice, etc…)
En Java los hilos se pueden crear y destruir en
cualquier momento de la ejecución del programa, no
tienen que seguir la rígida estructura de los programas
de SimpleConcurrent
Concurrencia en los Lenguajes de Programación
78. 78
public class Programa {
public static void main(String[] args) {
Thread t = new Thread(()->{
System.out.println("Soy un hilo");
});
t.start();
t.join();
}
}
Comienza la ejecución del hilo
El código que se ejecuta
en un hilo de forma concurrente
Concurrencia en Java
Concurrencia en los Lenguajes de Programación
Se bloquea hasta que el hilo termina
79. 79
Concurrencia en Java
•En java se pueden usar otros modelos de concurrencia
con librerías
Actores:
Akka: http://akka.io/
Quasar: http://www.paralleluniverse.co/quasar/
Memoria software transaccional:
Multiverse: http://multiverse.codehaus.org
Comunicando procesos secuenciales (CSP):
JCSP: http://www.cs.kent.ac.uk/projects/ofa/jcsp/
Programación funcional:
Framework Collections en Java 8:
http://java.dzone.com/articles/title-devoxx-2012-java-8
RxJava: https://github.com/Netflix/RxJava
Concurrencia en los Lenguajes de Programación
81. 81
Concurrencia en C/C++
•C/C++ es una familia de lenguajes de
programación de bajo nivel
•Están diseñados para el acceso al hardware y
el rendimiento
•Esto hace que se usen especialmente en:
Programación de sistemas
Sistemas empotrados con recursos limitados
Computación de altas prestaciones
Concurrencia en los Lenguajes de Programación
82. 82
Concurrencia en C/C++
• Existen diversos estándares de C/C++
C90, C99, C++03, C++11, C++14
• Existen muchos compiladores de C/C++ con diferentes
soporte de los estándares
gcc: http://gcc.gnu.org/
clang: http://clang.llvm.org/
VisualC++: http://www.microsoft.com/visualstudio/
Intel C/C++ Compilers:
http://software.intel.com/en-us/c-compilers/
Hay muchos más… (http://en.wikipedia.org/wiki/C99)
Concurrencia en los Lenguajes de Programación
83. 83
Concurrencia en C/C++
•Existen tres enfoques para programación
concurrente en C/C++
Concurrencia en el lenguaje: Extensiones del lenguaje
no estándar que “paralelizan” el código
automáticamente para que algunas partes sean
ejecutadas en paralelo
Concurrencia con librerías de terceros: Librerías no
estándar para el desarrollo de programas concurrentes
Concurrencia en librería estándar: Funcionalidad
estándar para implementar programas concurrentes
Concurrencia en los Lenguajes de Programación
84. 84
Concurrencia en C/C++
•Concurrencia en el lenguaje
Existen extensiones de algunos compiladores
Amplían C/C++ con nuevas palabras reservadas
Usando esas palabras reservadas se transforma el
código para que sea ejecutado en diferentes hilos
de ejecución
Normalmente transforman bucles de secuencial a
paralelo
Más importantes: OpenMP e Intel Cilk Plus
Concurrencia en los Lenguajes de Programación
85. 85
Concurrencia en C/C++
•OpenMP
Disponible en los compiladores Intel C/C++, gcc, …
Permite ejecutar concurrentemente bucles,
bloques, etc.
Trabaja con un esquema fork / join para que un hilo
principal reparta el trabajo en hilos y espere al
resultado de todos ellos
http://openmp.org/
Concurrencia en los Lenguajes de Programación
86. 86
Concurrencia en C/C++
•Ejemplo OpenMP
Concurrencia en los Lenguajes de Programación
double ProductoPunto(double* a, double* b, int size)
{
double c = 0;
#pragma omp parallel for reduction(+:c)
for (int i = 0; i < size; ++i)
{
c += a[i]*b[i];
}
return c;
}
Con este comando se permite paralelizar
la ejecución de las iteraciones del buble y
luego “reducir” los valores de cada hilo
con una operación de suma
87. 87
Concurrencia en C/C++
•Intel Cilk Plus
Disponible en los compiladores Intel C/C++ y gcc
Usando sólo tres nuevas palabras clave se pueden
paralelizar operaciones sobre arrays
http://www.cilkplus.org/
Concurrencia en los Lenguajes de Programación
88. 88
Concurrencia en C/C++
•Ejemplo Intel Cilk Plus
Concurrencia en los Lenguajes de Programación
int fib(int n)
{
if (n < 2)
return n;
int x = cilk_spawn fib(n-1);
int y = fib(n-2);
cilk_sync;
return x + y;
}
Con este comando se indica que fib(n-1)
se puede ejecutar en un nuevo hilo en
paralelo con el hilo principal que
ejecutará fib(n-2)
Con este comando se indica que
el hilo se bloquea hasta que han
terminado los otros hilos
89. 89
Concurrencia en C/C++
•Concurrencia con Librerías de terceros
La librería estándar de C++ era muy básica, y en la
práctica cada sistema operativo ofrecía su propio
conjunto de librerías
Win32: Librería de la familia de sistemas operativos
windows (95, 98, XP, 2000,Vista, 8..)
POSIX, GTK, KDE…: Librerías de la familia de
sistemas operativos UNIX / Linux (Red Hat,
Ubuntu…)
Concurrencia en los Lenguajes de Programación
90. 90
Concurrencia en C/C++
•Win32 y POSIX permiten la programación
concurrente en un modelo de memoria compartida
Cada librería con tipos y funciones (API) diferentes
Win32
API win32 ofrece las primitivas de concurrencia.
http://msdn.microsoft.com/en-us/library/ms686937(v=vs.85).aspx
Otras librerías concurrentes paraVisual C++:
http://archive.msdn.microsoft.com/concrtextras
POSIX
Podemos referirnos a ellos como Native POSIXThreads Library
(NPTL) o pthreads
https://computing.llnl.gov/tutorials/pthreads/
Concurrencia en los Lenguajes de Programación
91. 91
Ejemplo
POSIX pthreads
void *thr_func(void *arg) {
printf("Soy un hilon");
pthread_exit(NULL);
}
int main(int argc, char **argv) {
pthread_t thr;
pthread_create(&thr, NULL, thr_func, NULL);
pthread_join(thr[i], NULL);
return 0;
}
Comienza la
ejecución del hilo
El código que se ejecuta
en un hilo de forma concurrente
Se bloquea hasta que el hilo termina
92. 92
Ejemplo
win32Threads
DWORD WINAPI thr_func(LPVOID args) {
printf("Soy un hilon");
return 0;
}
int main(int argc, char **argv) {
DWORD thrId;
HANDLE thr;
thr = CreateThread(0,0, thr_func,0,0,&thrId);
WaitForSingleObject(thr, INFINITE);
CloseHandle(thr);
return 0;
}
Comienza la
ejecución del hilo
El código que se ejecuta
en un hilo de forma concurrente
Se bloquea hasta que el hilo termina
93. 93
Concurrencia en C/C++
• Existen algunas librerías multiplataforma para
programación concurrente con memoria compartida
que se pueden usar en Unix, Mac y Windows
Boost
También tiene otro tipo de funcionalidades
http://www.boost.org/doc/libs/1_43_0/doc/html/thread.html
IntelThreading Building Blocks
También dispone de herramientas de alto nivel (estructuras de
datos, gestión de hilos, …)
http://threadingbuildingblocks.org/
Concurrencia en los Lenguajes de Programación
94. 94
Concurrencia en C/C++
•Concurrencia en librería estándar
C++11 define una forma estándar de crear hilos
Concurrencia en los Lenguajes de Programación
#include <thread>
#include <iostream>
int main(){
std::thread t1([](){
std::cout << "Hello from thread " << std::endl;
});
t1.join();
return 0;
}
https://www.classes.cs.uchicago.edu/archive/2013/spring/12300-1/labs/lab6/
95. 95
Concurrencia en C/C++
•Conclusiones
Las plataformas mayoritarias tienen librerías para
la programación concurrente de bajo nivel con
memoria compartida (win32, POSIX…)
El estándar C++11 ya proporciona una forma
estándar de gestionar hilos
Concurrencia en los Lenguajes de Programación
96. 96
Concurrencia en C/C++
•Conclusiones
Existen librerías multiplataforma que
proporcionan herramientas de más alto nivel
(Boost, IntelTBB…)
Se pueden usar variantes del lenguaje C/C++ que
ofrecen herramientas del alto nivel especialmente
diseñadas para paralelización de algoritmos
(OpenMP, Intel Cilk Plus…)
Concurrencia en los Lenguajes de Programación
98. 98
Concurrencia en JavaScript
• JavaScript es un lenguaje que se diseñó para ejecutarse en
el contexto de una página web dentro de un navegador
web
• Los navegadores actuales ejecutan el código JavaScript
con máquinas virtuales* (V8 de Chrome, IonMonkey en
Firefox…)
• JavaScript es el nombre “popular” del estándar
ECMAScript
• Muchos de los aspectos de la plataforma de desarrollo con
JavaScript se definen bajo el estándar HTML5
Concurrencia en los Lenguajes de Programación
* http://en.wikipedia.org/wiki/JavaScript_engine
99. 99
Concurrencia en JavaScript
•Concurrencia en primeras versiones de JS
– JavaScript se diseñó para añadir interactividad a una
página web
– Una página web es como una Interfaz gráfica de usuario
(GUI), que se suelen implementar con un único hilo de
ejecución (hilo de despacho de eventos)
– Por este motivo, JavaScript inicialmente sólo se podía
ejecutar en un único hilo de ejecución (single-threaded)
– No podía haber dos funciones ejecutándose a la misma
vez de forma concurrente
Concurrencia en los Lenguajes de Programación
100. 100
Concurrencia en JavaScript
•Concurrencia en primeras versiones de JS
– Y si se necesita hacer una petición al servidor al pulsar un
botón?
– Si hay un único hilo, la GUI se bloquea a la espera de la
respuesta?
– JavaScript implementa un modelo de programación
asíncrono
– Las operaciones de entrada/salida no son bloqueantes en JS
– En vez de esperarse a que llegue el resultado, se define qué
se ejecutará cuando llegue la respuesta
Concurrencia en los Lenguajes de Programación
101. 101
Concurrencia en JavaScript
•Concurrencia en primeras versiones de JS
Concurrencia en los Lenguajes de Programación
var oReq = new XMLHttpRequest();
oReq.addEventListener("load", function(){
console.log("Respuesta recibida");
console.log(this.responseText);
});
oReq.open("GET",
"http://example.org/example.txt");
oReq.send();
console.log("Petición enviada");
El método send no se bloquea
a la espera de la respuesta
El código que se
ejecutará cuando llegue
la respuesta se define
en una función
102. 102
Concurrencia en JavaScript
•Concurrencia en primeras versiones de JS
– Implementación del sleep
Concurrencia en los Lenguajes de Programación
setTimeout(function(){
alert("Hello");
}, 3000);
sleep(3000);
alert("Hello");
Esta sería la
implementación en un
lenguaje concurrente.
sleep(millis) es un
método bloqueante
En JS tenemos que
registrar lo que
queremos que suceda
cuando pasen 3000ms
103. 103
Concurrencia en JavaScript
•Concurrencia con WebWorkers
– El estándar WebWorkers dentro de HTML5 se
empezó a implementar en browsers en 2010 aprox
– Permite usar un modelo de programación concurrente
de paso de mensajes en JavaScript
– A los hilos en segundo plano se les denomina
WebWorkers (o simplemente workers)
– Los workers no usaban memoria compartida (hasta
ES2017), sólo se comunicaban mediante paso de
mensajes entre hilos
Concurrencia en los Lenguajes de Programación
104. 104
Concurrencia en JavaScript
•Concurrencia con WebWorkers
– En JavaScript el código siempre se ejecuta en
respuesta a un evento (carga de página, evento del
usuario, temporizador, llamada AJAX…)
– Un worker funciona de forma similar, sólo ejecuta
código ante la llegada de un mensaje desde el script
principal o desde otro worker
– Un worker también puede enviar mensajes de vuelta
Concurrencia en los Lenguajes de Programación
http://anders.janmyr.com/2013/02/web-workers.html
105. 105
Ejemplo
WebWorkers
self.addEventListener('message', function(e) {
//do somethin useful
self.postMessage(e.data);
}, false);
Código del hilo
(WebWorker)
var worker = new Worker('doWork.js');
worker.addEventListener('message',
function(e) {
console.log('Worker said: ', e.data);
}, false);
// Send data to the worker.
worker.postMessage('Hello World');
Script principal
doWork.js
Ejecución del hilo
(WebWorker) al enviarle un
mensaje
Código de respuesta al
recibir un mensaje del
WebWorker
Concurrencia en JavaScript
Concurrencia en los Lenguajes de Programación
106. 106
Concurrencia en JavaScript
• Actualmente se está popularizado el uso de JavaScript
fuera del navegador
• El más popular es el servidor web node.js (basado enV8
de Chrome) que utiliza librerías (módulos)
• Módulos para WebWorkers en node.js
https://npmjs.org/package/webworker-threads
• Módulos para la gestión directa de procesos en node.js
http://nodejs.org/api/child_process.html
Concurrencia en los Lenguajes de Programación
108. 108
Conclusiones
• Cada plataforma de desarrollo (lenguaje, sistema
operativo y librerías) tiene sus propios mecanismos de
programación concurrente
• Las plataformas que soportan el modelo de memoria
compartida:
Suelen ofrecer herramientas de bajo nivel similares:
Gestión de hilos y herramientas de sincronización
Habitualmente disponen de librerías de alto nivel:
Estructuras de datos concurrentes, herramientas avanzadas de
sincronización, otros modelos de programación concurrente…)
Concurrencia en los Lenguajes de Programación
109. 109
Conclusiones
•Existen plataformas muy extendidas que tienen un
soporte de concurrencia limitado o únicamente
ofrecen modelos de alto nivel (JavaScript, Go,
Erlang…)
•Esto se debe a que la programación concurrente es
compleja y se ha restringido en ámbitos en los que se
considera que no es imprescindible o se puede
ofrecer un modelo más sencillo
Concurrencia en los Lenguajes de Programación
110. 110
Conclusiones
•La programación concurrente no es una disciplina
nueva en informática
•Pero la llegada de los procesadores multicore ha
obligado a las plataformas de desarrollo a ofrecer
herramientas para aprovechar (y no desperdiciar)
todo esa potencia de cómputo
•En los próximos años evolucionarán y se
popularizarán las herramientas de concurrencia que
ofrecen las plataformas
Concurrencia en los Lenguajes de Programación
112. 112
Introducción
•Cualquier aplicación se puede implementar
con técnicas concurrentes
•Dependiendo del tipo de aplicación, se
obtiene una ventaja u otra:
Ofrecer un servicio interactivo a varios
clientes/tareas
Aprovechar la potencia de computación
En sistemas multi-core
Con tareas que esperan por entrada/salida
APLICACIONES CONCURRENTES
113. 113
Introducción
•La gran mayoría de las aplicaciones que usamos a
diario son concurrentes
Aplicaciones con interfaz de usuario: Las librerías de
interfaz de usuario siguen mayoritariamente la misma
estructura de separación en hilos (servicio interactivo y
facilidad de desarrollo)
Aplicaciones web: Cada petición a un servidor web se
procesa de forma concurrente (servicio interactivo)
APLICACIONES CONCURRENTES
114. 114
Aplicaciones con interfaz de usuario
•La mayoría de las librerías de interfaz de usuario
se ejecutan en un solo hilo
•A este hilo se le denomina “Hilo de despacho de
eventos” (Event dispatch thread)
•Todas las operaciones que utilicen elementos del
interfaz (primer plano) deben realizarse en ese
hilo
•Las operaciones en segundo plano deben
realizarse en otro hilo para no bloquear la interfaz
APLICACIONES CONCURRENTES
115. 115
Aplicaciones con interfaz de usuario
•Es habitual estudiar la programación dirigida
por eventos en contraposición a la
programación secuencial
En la programación secuencial el programador
define el flujo del programa de principio a fin
En la programación dirigida por eventos el
usuario dirige el flujo del programa interactuando
con los elementos del interfaz
APLICACIONES CONCURRENTES
117. 117
Aplicaciones con interfaz de usuario
•La pantalla “congelada” o la pantalla en gris
aparece cuando una tarea en el hilo de
despacho de eventos dura mucho tiempo
•Las librerías de interfaz de usuario ofrecen
mecanismos para ejecutar tareas en segundo
plano que tardan cierto tiempo
•Estas tareas de segundo plano pueden
actualizar el interfaz según progresan
APLICACIONES CONCURRENTES
119. 119
Aplicaciones web
•Históricamente, en las aplicaciones web cada
petición se procesa por un hilo diferente
•Esto permite ofrecer un servicio interactivo a
cada cliente
•La calidad del servicio se degrada de forma
paulatina
•El número total de hilos (peticiones
concurrentes) se configura en el servidor web
APLICACIONES CONCURRENTES
120. 120
Aplicaciones web
•Tener un hilo por cada petición presenta
problemas de escalabilidad
•Si para procesar una petición se hace una consulta
a la BBDD o a otro sistema, el hilo quedará a la
espera la mayor parte del tiempo
•El número de hilos de una aplicación está limitado
por diversos factores y no suele ser mayor de
10.000.
•http://en.wikipedia.org/wiki/C10k_problem
APLICACIONES CONCURRENTES
121. 121
Aplicaciones web
•Para evitar la limitación y los problemas de escalabilidad,
actualmente algunos servidores web no utilizan un hilo para
procesar “toda” la petición
•Cuando se atiende una petición al servidor y se quiere
hacer una operación de entrada/salida (por ejemplo una
consulta a la BBDD), en vez de que el hilo quede
bloqueado, define el código que se ejecutará cuando el
resultado esté disponible (callback)
•En ese momento el hilo queda libre para atender a una
nueva petición sin haber procesado completamente la
anterior.
APLICACIONES CONCURRENTES
122. 122
Aplicaciones web
•Este modelo de programación de servidores es
muy popular en la actualidad con servidores
como:
Nginx: Servidor web escrito en C que dispone de
módulos para PHP. Se usa sustituyendo a Apache
Vert.x: Servidor programado en Java
Node.js: Plataforma programada en JavaScript
APLICACIONES CONCURRENTES
123. 123
Aplicaciones web
•Independientemente del tipo de servidor web,
cuando se procesa una petición se puede acceder a
varias zonas de memoria:
ServletContext: Compartida entre las peticiones de
todos los usuarios de la web
HttpSession: Compartida entre las peticiones de un
único usuario
•La información compartida tiene que ser thread-safe,
porque varios hilos pueden acceder a su información
concurrentemente
APLICACIONES CONCURRENTES
125. 125
Programación asíncrona
•Programación asíncrona
– La programación asíncrona es un modelo de
programación en el que los hilos no quedan
bloqueados en E/S
– También llamada no bloqueante o reactiva
– Como no hay bloqueo en E/S, únicamente existe
un hilo por procesador
– No hay cambio de contexto entre hilos, no hay
problema de escalabilidad
126. 126
Programación asíncrona
•¿Cómo se programa de forma asíncrona?
– Haciendo que el código nunca quede bloqueado
– Necesita soporte de las librerías de I/O no
bloqueante
●
Java no tuvo Non-blocking I/O hasta Java 1.4 y
fue mejorado en Java 7
●
En C la función select permite Non-blocking I/O
127. 127
Programación asíncrona
•¿Cómo se programa de forma asíncrona?
– Patrones de diseño asíncronos
– Soporte propio en el lenguaje de
programación
129. const fs = require('fs');
fs.readFile('/etc/hosts', function (err, data) {
if (err) throw err;
console.log(data.toString());
});
Callbacks
El método readFile no se bloquea
a la espera de la respuesta
La callback que es
llamada al terminar se
suele denominar
continuation
132. 132
Programación asíncrona
•Soporte propio en el lenguaje de programación
– Se programa como si fuera síncrono/bloqueante
pero el código no bloquea el hilo
●
JavaScript ES7: async/await
●
Go: Gorturinas
●
Kotlin: Corrutinas
●
C#: async/await
●
Java?: Proyecto Loom (en desarrollo)
133. 133
Async/Await en JavaScript
Promesas Async / Await
getData()
.then(a => {
return getMoreData(a)
})
.then(b => {
return getMoreData(b)
})
.then(c => {
console.log(c);
})
.catch(e => {
console.error(e);
})
try {
let a = await getData();
let b = await getMoreData(a);
let c = await getMoreData(b);
console.log(c);
} catch(e) {
console.error(e);
}
134. 134
Programación asíncrona
•Pros y contras de la programación asíncrona
– Si el lenguaje no tiene un soporte adecuado el
código es mucho más complejo de desarrollar y
depurar
– Hay veces que no merece la pena el aumento de
complejidad
– La ganancia en rendimiento sólo se obtiene con
cargas de trabajo muy elevadas
135. 135
Programación asíncrona en Java
•I/O no bloqueante
– Se incorporó en Java 1.4 (2002)
– Se mejoró en Java 7 (2011)
•Expresiones lambda
– Permiten implementar callbacks de forma
razonable (antes se hacía con clases anónimas)
– Incorporadas en Java 8 (2014)
136. 136
Programación asíncrona en Java
•CompletableFuture
– Una construcción parecida a las Promesas de
JavaScript
– Incorporada en Java 8 (2014)
•Librerías Programación Reactiva Funcional (2014+)
– Vert.x
– Akka Streams
– RxJava
– Reactive-streams (interoperabilidad entre librerías react)
137. 137
Programación asíncrona en Java
•Flow
– Estandar de interoperabilidad de librerías reactivas
– Incorporado en Java 9 (Sept 2017)
•Spring 5.0
– Reactividad en aplicaciones Spring
– Interoperable con las demás librerías reactivas
– Publicado en Sept 2017
138. 138
Programación asíncrona en JavaScript
•JavaScript es un lenguaje no bloqueante
desde el diseño
•Inicialmente las librerías usaban el patrón de las
callbacks cuando hay I/O bloqueante
•Las Promesas se estandarizaron en ES6 (aunque había
implementaciones previas)
•Dispone de una librería de Programación Reactiva
Funcional RxJS
140. 140
Programación funcional
•La programación reactiva usa muchos
conceptos del procesamiento declarativo de
estructuras de datos de la programación
funcional
•Veremos primero cómo se usa la programación
funcional en lenguajes imperativos como Java
y JavaScript
142. 142
Java Streams
•Los streams (flujos) permiten procesar
colecciones de elementos con un estilo
funcional (declarativo)
•Ventajas frente al estilo actual:
Más compacto y de alto nivel
Fácilmente paralelizable
No se necesita tener todos los elementos en
memoria para empezar a procesar
143. 143
•Se quiere calcular la edad media
int sum = 0;
int average = 0;
for (Person person : people) {
sum += person.getAge();
}
if (!list.isEmpty()) {
average = sum / list.size();
}
Java Streams
144. 144
•Se quiere calcular la edad media de los menores de 20
int sum = 0;
int n = 0;
int average = 0;
for (Person person : people) {
if (person.getAge() > 20) {
n++;
sum += person.getAge() ;
}
}
if (n > 0) {
average = sum / n ;
}
Java Streams
145. 145
•La programación imperativa es muy verbosa porque
se indica qué se quiere y cómo se consigue
•La programación declarativa es mucho más
compacta porque basta indicar qué se quiere
select sum(age)
from Person
where age > 20
Sentencia SQL equivalente
Java Streams
146. 146
•Los streams (flujos) permiten aplicar operaciones de
mapeo, filtrado y reducción a colecciones de datos
•Un stream es una secuencia de elementos que sólo
pueden procesarse una vez
•Puede generarse de forma dinámica (no tiene que
estar toda la secuencia en memoria)
•Esto permite implementaciones muy eficientes de
las operaciones sin crear estructuras de datos
intermedias
Java Streams
147. 147
•La forma más habitual de crear un stream es
partiendo de una colección
int sumOver20 = persons.stream()
.map(Person::getAge)
.filter(age -> age > 20)
.reduce(0, Integer::sum);
Java Streams
select sum(age)
from Person
where age > 20
149. 149
•Lodash
– Librería muy usada con utilidades
– Una de ellas es la programación
funcional (lodash/fp)
– Reimplementación de Underscore.js
Programación funcional en JavaScript
https://lodash.com/
https://github.com/lodash/lodash/wiki/FP-Guide
150. 150
•Sin Lodash
Programación funcional en JavaScript
https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore
var array1 = [1, 2, 3]
var array2 = array1
.filter(n => n % 2 != 0)
.map((value, index) => value * 2);
console.log(array2) // output: [2, 6]
151. 151
•Existen librerías inspiradas en los streams de Java
para JavaScript
Programación funcional en JavaScript
http://winterbe.github.io/streamjs/
Stream(people)
.filter({age: 23})
.flatMap("children")
.map("firstName")
.distinct()
.filter(/a.*/i)
.join(", ");
https://github.com/winterbe/sequency
152. 152
Programación Reactiva Funcional
•Unir los conceptos de la programación funcional y la
programación asíncrona
•Se aplica a flujos de eventos (streams) que van
llegando a lo largo del tiempo
•Permite usar los operadores básicos de programación
funcional: map, filter, flatMap…
•Añade nuevos operadores basados en tiempo: delay,
timeout
153. 153
Programación Reactiva Funcional
•El soporte de async / await en el lenguaje no
está diseñado para flujos de eventos (streams)
•La programación reactiva funcional se está
popularizando para tratar flujos de eventos
tanto en backend como en frontend (Angular)
•Existen múltiples librerías de Functional
Reactive Programming (FRP) para Java y
JavaScript
160. 160
Programación asíncrona en Spring
•Back pressure (Control de flujo)
– Los sistemas asíncronos tienen un
mecanismo para notificar al generador de
eventos (productor) cuándo el sistema se
empieza a saturar
– El protocolo de red RSocket permite
implementar protocolos que tienen en
cuenta este mecanismo de control
http://rsocket.io/
162. 162
Conclusiones
• En los próximos años es previsible que los procesadores
tengan cada vez más núcleos de procesamiento
• La programación concurrente será la única forma de
aumentar la potencia de cómputo de los dispositivos al
no poder aumentar la velocidad de ejecución
• Para aprovecharla, los programas secuenciales existentes
se tienen que reimplementar y los nuevos se tienen que
diseñar dividiendo el procesamiento en tareas que
puedan ejecutarse en paralelo
Introducción a la Programación Concurrente
163. 163
Conclusiones
•Pese a que existen muchos modelos de
programación concurrente, el más utilizado sigue
siendo el modelo de bajo nivel de estado compartido
con cerrojos
•Es el más complejo de usar correctamente, pero es el
más potente
•Es conveniente dominar otros modelos de
concurrencia porque pueden ser más adecuados para
ciertos tipos de programas (actores, CSP, funcional,
etc…)
Introducción a la Programación Concurrente
164. 164
Conclusiones
• Desarrollar programas concurrentes es mucho más
complejo que desarrollar programas secuenciales
Son más difíciles de programar
Es más difícil comprobar que su funcionamiento es el correcto,
porque hay que considerar cómo se comportan con uno o varios
procesadores, con la misma o diferentes velocidades
Que una ejecución sea correcta con unos datos de entrada no
implica que todas las ejecuciones sean correctas con esos
mismos datos (como ocurre con los programas secuenciales).
Hay ejecuciones problemáticas que pueden aparecer sólo en
raras ocasiones (con el sistema en producción y mucha carga)
Introducción a la Programación Concurrente
166. 166
Conclusiones
•Pese a que es un campo maduro, los modelos de
concurrencia actuales siguen evolucionando para
facilitar la construcción de programas concurrentes
evitando sus muchas dificultades
•Eso implica que constantemente aparecer nuevos
modelos y técnicas
•Actualmente la tendencia es usar técnicas
declarativas propias de la programación funcional
para definir operaciones que puedan ejecutarse de
forma concurrente
Introducción a la Programación Concurrente