Programación concurrente con GroovyWednesday, May 30, 12
Hola!              Mario García (@marioggar)                    Freelance Software alchemist                    Groovy pas...
¿Qué es GPars?              Es un framework que proporciona a los desarrolladores              Java una forma segura e int...
¿Por qué usar GPars?              Usas Groovy o Java              Quieres escribir código empleando concurrencia ó        ...
¿Qué vamos a ver?              Ayudas a nivel de código              Conceptos a nivel de arquitectura              Protec...
Ayudas a nivel de códigoWednesday, May 30, 12
Ayudas a nivel de código              Estas ayudas nos permitirán escribir código              concurrente variando poco o...
Parallel ArraysWednesday, May 30, 12
Parallel Arrays              Todos los métodos que utilizabamos sobre colecciones              tienen ahora a su “hermano ...
def findAllPeopleNameOver30AndSingle(people){                  people.                   findAll{it.age >30}.               ...
def findAllPeopleNameOver30AndSingle(people){                GParsPool.withPool {                  people.                 ...
Ayudas a nivel de código                    GParsPool.withPool                        La clase GParsPool es la que permite...
Parallel Arrays              Meta-class enchancer                    Si no queremos “encerrar” nuestro código con         ...
def findAllPeopleNameOver30AndSingle(people){                ParallelEnhancer.enhanceInstance(people)                people...
Parallel Arrays              Umm no podría hacerlo con menos?              Claro!! :)              Podemos seguir utilizan...
def findAllPeopleNameOver30AndSingle(people){                ParallelEnhancer.enhanceInstance(people)                people...
Parallel Arrays              ...Bien manteniendo nuestro método original e              invocandole pasandole como paramet...
def findAllPeopleNameOver30AndSingle(people){               people.                  findAll{it.age > 30}.                  ...
Parallel Arrays              Un gatito muere en algun lugar cuando:                    Se accede a una colección not-threa...
Parallel Arrays                    def findAllPeopleNameOver30AndSingle(people){                        def result = []    ...
Map/ReduceWednesday, May 30, 12
Map/Reduce              La DSL Map/Reduce para el manejo de colecciones da              a GPars un sabor más “funcional”. ...
Map/Reduce             def findAllPeopleNameOver30AndSingle(people){                ParallelEnhancer.enhanceInstance(people...
Map/Reduce              Cada ejecución xxxParallel hace la conversión              paralela-->normal para cumplir con el c...
Map/Reduce               soccerDays.parallel.                  filter{it.fieldViewers > 1000000}.                  map{[it,(...
Ejecución asincrona              Combinar la ejecución asincrona de varias tareas y              pasarlas como argumentos ...
Ejecución asincrona              Ejemplo: Media Aritmetica                        Composición de closures:                ...
Ejecución asincrona                        def peopleYears = {people-> people*.age.sum()}.asyncFun()                      ...
Conceptos a nivel de         arquitecturaWednesday, May 30, 12
Concetos a nivel...              En esta parte veremos partes de GPars más              avanzadas que requieren que plante...
Dataflow              GPars nos permite definir procesos como un flujo de              datos en lugar de como un flujo de ejec...
Dataflow                Upps...Wednesday, May 30, 12
Dataflow                               result                        top                 states                        rows...
Dataflow              Demo: Tornados en Estados Unidos                    Recuperamos todos los ocurridos (rows)           ...
Dataflow                        def flow = new Dataflows()                        task {              1)          flow.rows = ...
Dataflow              Flow:                    1) Se descargan los datos de los tornados y unos datos                    re...
Dataflow              Solución bastante elegante estableciendo              dependencias entre datos              Cuidado c...
ActorsWednesday, May 30, 12
Actors              NO ESTOS NOWednesday, May 30, 12
Actors              Los actores nos permiten la cordinación explicita entre              procesos asincronos.             ...
Actors              Inspirado en los Actores de Scala pero mejorado.                    Actores con estado: Solo en casos ...
Actors              Demo: F1                    Tenemos una serie de corredores cuyos coches                    tienen que...
¿Para qué podemos usarlo?Wednesday, May 30, 12
¿Para qué?              Ideal para:                    Procesos de calculo matemático                    Procesos en arbol...
¿Para qué?              Ideal para:                    Programación funcional (Map/Reduce)                    Programación...
GPars es mucho más              Agents              Speculations              STM (Software Transactional Memory)         ...
GPars es mucho más              Página proyecto                    http://gpars.codehaus.org/              Libros         ...
GPars es mucho más              Blogs, videos...                    Paul King (Video) GPars Concurrency                   ...
Q&AWednesday, May 30, 12
Próxima SlideShare
Cargando en…5
×

Programación concurrente con GPars

923 visualizaciones

Publicado el

GPars talk at @MadridGUG 05/2012

Publicado en: Tecnología
0 comentarios
0 recomendaciones
Estadísticas
Notas
  • Sé el primero en comentar

  • Sé el primero en recomendar esto

Sin descargas
Visualizaciones
Visualizaciones totales
923
En SlideShare
0
De insertados
0
Número de insertados
3
Acciones
Compartido
0
Descargas
7
Comentarios
0
Recomendaciones
0
Insertados 0
No insertados

No hay notas en la diapositiva.

Programación concurrente con GPars

  1. 1. Programación concurrente con GroovyWednesday, May 30, 12
  2. 2. Hola! Mario García (@marioggar) Freelance Software alchemist Groovy passionate! Madrid Groovy User Group member (@MadridGUG)Wednesday, May 30, 12
  3. 3. ¿Qué es GPars? Es un framework que proporciona a los desarrolladores Java una forma segura e intuitiva de manejar tareas concurrentes Escrito en su mayoría en Java Sospechosos habituales: Vaclav Pech (Jetbrains)Wednesday, May 30, 12
  4. 4. ¿Por qué usar GPars? Usas Groovy o Java Quieres escribir código empleando concurrencia ó paralelismo Vas a usar hardware de varios nucleos La programación concurrente siempre te ha parecido muy compleja. PORQUE ESTA INCLUIDO EN GROOVYWednesday, May 30, 12
  5. 5. ¿Qué vamos a ver? Ayudas a nivel de código Conceptos a nivel de arquitectura Protección de objetos compartidosWednesday, May 30, 12
  6. 6. Ayudas a nivel de códigoWednesday, May 30, 12
  7. 7. Ayudas a nivel de código Estas ayudas nos permitirán escribir código concurrente variando poco o nada nuestro código actual. Parallel Arrays (fork/join) Syntaxis mas funcional (map/reduce/filter) Ejecución asincrona de funciones (closures)Wednesday, May 30, 12
  8. 8. Parallel ArraysWednesday, May 30, 12
  9. 9. Parallel Arrays Todos los métodos que utilizabamos sobre colecciones tienen ahora a su “hermano paralelo”. findAll --> findAllParallel, collect--> collectParallel Estos métodos nos permiten realizar las mismas tareas de manera parallela cordinandolas a la finalizacion de la misma. Basado en Fork/Join jsr166Wednesday, May 30, 12
  10. 10. def findAllPeopleNameOver30AndSingle(people){ people. findAll{it.age >30}. collect{it.name} }Wednesday, May 30, 12
  11. 11. def findAllPeopleNameOver30AndSingle(people){ GParsPool.withPool { people. findAllParallel{it.age >30}. collectParallel{it.name} } }Wednesday, May 30, 12
  12. 12. Ayudas a nivel de código GParsPool.withPool La clase GParsPool es la que permite el DSL de concurrencia para collecciones y objetos groovyx.gpars.GParsPool El método withPool puede tomar como parametros el numero de hilos creados en el pool y un manejador de excepcionesWednesday, May 30, 12
  13. 13. Parallel Arrays Meta-class enchancer Si no queremos “encerrar” nuestro código con withPool{ ... } podemos utilizar la clase ParallelEnhancer groovyx.gpars.ParallelEnhancer Agregara al metaClass de nuestra coleccion las nuevas funciones concurrentes.Wednesday, May 30, 12
  14. 14. def findAllPeopleNameOver30AndSingle(people){ ParallelEnhancer.enhanceInstance(people) people. findAllParallel{it.age > 30}. collectParallel{it.name} }Wednesday, May 30, 12
  15. 15. Parallel Arrays Umm no podría hacerlo con menos? Claro!! :) Podemos seguir utilizando la misma sintaxis de colecciones bien utilizando el método makeConcurrent() sobre una colección...Wednesday, May 30, 12
  16. 16. def findAllPeopleNameOver30AndSingle(people){ ParallelEnhancer.enhanceInstance(people) people.makeConcurrent(). findAll{it.age > 30}. collect{it.name} }Wednesday, May 30, 12
  17. 17. Parallel Arrays ...Bien manteniendo nuestro método original e invocandole pasandole como parametro una colección concurrente.Wednesday, May 30, 12
  18. 18. def findAllPeopleNameOver30AndSingle(people){ people. findAll{it.age > 30}. collect{it.name} } ParallelEnhancer.enhanceInstance(people) findAllPeopleNameOver30AndSingle( people.makeConcurrent() )Wednesday, May 30, 12
  19. 19. Parallel Arrays Un gatito muere en algun lugar cuando: Se accede a una colección not-thread-safe desde un método “parallel” Se crea una closure con estado. Todas las closures que se pasan como parametro a un método paralelo deben de ser thread-safe o dicho de otro modo deben ser “sin estado”Wednesday, May 30, 12
  20. 20. Parallel Arrays def findAllPeopleNameOver30AndSingle(people){ def result = [] ParallelEnhancer.enhanceInstance(people) people. findAllParallel{it.age > 30}. eachParallel{ result << it.name} result } MiaoooouuuuWednesday, May 30, 12
  21. 21. Map/ReduceWednesday, May 30, 12
  22. 22. Map/Reduce La DSL Map/Reduce para el manejo de colecciones da a GPars un sabor más “funcional”. Map/Reduce “rinde más rápido” que los métodos xxxParallel para operaciones encadenadas sobre una coleccion paralela Algunos métodos map/reduce se pueden usar de la misma manera que los metodos xxxParallel ya que tienen semanticas parecidasWednesday, May 30, 12
  23. 23. Map/Reduce def findAllPeopleNameOver30AndSingle(people){ ParallelEnhancer.enhanceInstance(people) people.parallel. filter{it.age > 30}. map{it.name}.collection }Wednesday, May 30, 12
  24. 24. Map/Reduce Cada ejecución xxxParallel hace la conversión paralela-->normal para cumplir con el contrato de los métodos no paralelos. Los métodos Map/Reduce se ejecutan sobre una la colección paralela. Usamos la propiedad parallel para acceder a ella. Los métodos Map/Reduce devuelven una colección paralela. Cuando queramos que devuelvan una colección normal utilizamos la propiedad collectionWednesday, May 30, 12
  25. 25. Map/Reduce soccerDays.parallel. filter{it.fieldViewers > 1000000}. map{[it,(it.soccerPlayers / it.fieldViewers) * 100]}. filter{it[1] > 0.018}. map{it[0].day}.collectionWednesday, May 30, 12
  26. 26. Ejecución asincrona Combinar la ejecución asincrona de varias tareas y pasarlas como argumentos a otras funciones Hay tareas que se pueden descomponer en varias subtareas más sencillas Mientras que habrá subtareas que tarden en ejecutarse, puede que otras solo tarden un momento Si ejecutaramos secuencialmente las tareas, las pesadas bloquearian a las ligeras.Wednesday, May 30, 12
  27. 27. Ejecución asincrona Ejemplo: Media Aritmetica Composición de closures: Hay que dividir la computación del problema en diferentes closures La ejecución de cada closure por separado es inmutable, no depende de los datos de la otra Se combinaran en una tercera closure que cordinará los resultados de ambasWednesday, May 30, 12
  28. 28. Ejecución asincrona def peopleYears = {people-> people*.age.sum()}.asyncFun() def howManyPeople = {people-> people.size()}.asyncFun() def avg = {yearsSum,peopleSize-> yearsSum/peopleSize }.asyncFun() avg( peopleYears(people), howManyPeople(people) )Wednesday, May 30, 12
  29. 29. Conceptos a nivel de arquitecturaWednesday, May 30, 12
  30. 30. Concetos a nivel... En esta parte veremos partes de GPars más avanzadas que requieren que planteemos nuestra aplicación de otra manera Dataflow ActoresWednesday, May 30, 12
  31. 31. Dataflow GPars nos permite definir procesos como un flujo de datos en lugar de como un flujo de ejecución Se genera un arbol de dependencias entre datosWednesday, May 30, 12
  32. 32. Dataflow Upps...Wednesday, May 30, 12
  33. 33. Dataflow result top states rows Esto esta mejor...Wednesday, May 30, 12
  34. 34. Dataflow Demo: Tornados en Estados Unidos Recuperamos todos los ocurridos (rows) Recuperamos el maestro de estados (states) Recogemos los 3 más peligrosos (result) Recogemos los nombres (result) Contabilizamos fecha de finalización (end)Wednesday, May 30, 12
  35. 35. Dataflow def flow = new Dataflows() task { 1) flow.rows = getTornadoRows() flow.remoteData = getSimulatedDataFromARemoteHost() } 2) task {flow.states = getStateRows()} 3) task {flow.top = ... } task { flow.result = flow.top.collect{data-> 4) flow.states.find{s-> s.stateCode == data.stateCode}.stateName } flow.end = System.currentTimeMillis() }Wednesday, May 30, 12
  36. 36. Dataflow Flow: 1) Se descargan los datos de los tornados y unos datos remotos (Estos ultimos hacen esperar un poco el proceso) 2) Esta tarea como no tiene ninguna dependencia se ejecuta a la vez que la tarea uno evitando la espera del proceso remoto 3) Se ejecuta cuando se han resuelto las variables de la tarea 1 4) Se ejecuta cuando se han resuelto las variables de las tareas 2 y 3 (flow.top y flow.states)Wednesday, May 30, 12
  37. 37. Dataflow Solución bastante elegante estableciendo dependencias entre datos Cuidado con las dependencias circulares == deadlock No lo recomiendo para arboles “muy grandes”. Se pierde el objetivo y se puede acabar en el punto anterior.Wednesday, May 30, 12
  38. 38. ActorsWednesday, May 30, 12
  39. 39. Actors NO ESTOS NOWednesday, May 30, 12
  40. 40. Actors Los actores nos permiten la cordinación explicita entre procesos asincronos. Recomendado para tareas complejas con dependencias de paso de mensajes entre ambas. Simula el paradigma de envio de mensajes (send,reply)Wednesday, May 30, 12
  41. 41. Actors Inspirado en los Actores de Scala pero mejorado. Actores con estado: Solo en casos concretos Actores sin estado: recomendadosWednesday, May 30, 12
  42. 42. Actors Demo: F1 Tenemos una serie de corredores cuyos coches tienen que notificar a direccion de carrera su posición. Actores implicados Conductores: Notifican su posición Comisario de carrera: Notifica el estado de la carreraWednesday, May 30, 12
  43. 43. ¿Para qué podemos usarlo?Wednesday, May 30, 12
  44. 44. ¿Para qué? Ideal para: Procesos de calculo matemático Procesos en arbol con nodos inmutables pero dependientes como por ejemplo: Ejemplo: Media aritmetica. La suma de elementos me la da un servicio que tarda x, pero mientras espero puedo calcular el numero total de elementos. En general procesos en los que tienes que componer datos dependiendo de otros que provinenen de diferentes fuentes heterogeneas y con alta latencia.Wednesday, May 30, 12
  45. 45. ¿Para qué? Ideal para: Programación funcional (Map/Reduce) Programación orientada a eventos (Actores)Wednesday, May 30, 12
  46. 46. GPars es mucho más Agents Speculations STM (Software Transactional Memory) ...Wednesday, May 30, 12
  47. 47. GPars es mucho más Página proyecto http://gpars.codehaus.org/ Libros Groovy In Action (2nd Ed) (Contiene un capítulo dedicado unicamente a GPars)Wednesday, May 30, 12
  48. 48. GPars es mucho más Blogs, videos... Paul King (Video) GPars Concurrency http://www.youtube.com/watch?v=dUDKnIIWw48 Tomas Lin: Grails/Gorm con GPars http://fbflex.wordpress.com/2010/06/11/writing-batch-import-scripts-with- grails-gsql-and-gpars/ Arturo Herrero (Slide) Functional Groovy http://www.slideshare.net/arturoherrero/functional-programming-with-groovyWednesday, May 30, 12
  49. 49. Q&AWednesday, May 30, 12

×