Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Let's talk concurrency

Plataformatec
September 21, 2012

Let's talk concurrency

For a long time, the de facto way of doing multi-core concurrency was using threads. However, the complexity of manipulating threads and state affected negatively how developers perceive concurrency. Fortunately, languages like Clojure and Erlang implement new paradigms that aim to make concurrency easier.

In this talk, José Valim is going to discuss the role state play in concurrency and introduce different paradigms for multi-core concurrency, like Actors and Software Transactional Memory, explaining their trade-offs and why they matter to us developers.

Plataformatec

September 21, 2012
Tweet

More Decks by Plataformatec

Other Decks in Technology

Transcript

  1. A tale by @josevalim from @plataformatec
    CONCURRENCY
    LET’S TALK
    Friday, September 21, 2012

    View Slide

  2. Friday, September 21, 2012

    View Slide

  3. Core Team Member
    Friday, September 21, 2012

    View Slide

  4. Friday, September 21, 2012

    View Slide

  5. CONCURRENCY
    LET’S TALK
    Friday, September 21, 2012

    View Slide

  6. “Execute several
    tasks simultaneously”
    Friday, September 21, 2012

    View Slide

  7. Server Server Server Server
    Friday, September 21, 2012

    View Slide

  8. Server
    Friday, September 21, 2012

    View Slide

  9. MULTI
    CORE
    SINGLE
    PROCESS
    Friday, September 21, 2012

    View Slide

  10. state
    concurrency
    off
    off
    Friday, September 21, 2012

    View Slide

  11. The Declarative Model
    Because mathematics is awesome!
    Friday, September 21, 2012

    View Slide

  12. •no mutation
    •no concurrency
    •just functions
    Friday, September 21, 2012

    View Slide

  13. factorial = lambda do |x|
    case x
    when 0
    1
    else
    x * factorial.(x-1)
    end
    end
    print factorial.(10)
    # => 3628800
    Friday, September 21, 2012

    View Slide

  14. Determinism
    Same input = > same output
    Friday, September 21, 2012

    View Slide

  15. •no i/o
    •no random
    •no side-effects
    •always returns the same result
    Friday, September 21, 2012

    View Slide

  16. lambda do |a, b|
    c = expensive_function.(a)
    d = also_expensive.(b)
    c + d
    end
    Friday, September 21, 2012

    View Slide

  17. lambda do |a, b|
    c = expensive_function.(a)
    d = also_expensive.(b)
    c + d
    end
    a = 1
    Friday, September 21, 2012

    View Slide

  18. lambda do |1, b|
    c = 42
    d = also_expensive.(b)
    c + d
    end
    Friday, September 21, 2012

    View Slide

  19. lambda do |a, b|
    c = expensive_function.(a)
    d = also_expensive.(b)
    c + d
    end
    Friday, September 21, 2012

    View Slide

  20. lambda do |a, b|
    d = also_expensive.(b)
    c = expensive_function.(a)
    c + d
    end
    Friday, September 21, 2012

    View Slide

  21. Haskell
    Using determinism for
    performance and expressiveness
    Friday, September 21, 2012

    View Slide

  22. l = lambda { |a,b,c| a + b + c }
    l.(1, 2, 3) #=> 6
    l.curry #=> #
    l.curry.(1) #=> #
    l.curry.(1).(2).(3) #=> 6
    Currying
    Friday, September 21, 2012

    View Slide

  23. l = lambda { |a,b| a * b }
    double = l.curry.(2)
    triple = l.curry.(3)
    Currying
    Friday, September 21, 2012

    View Slide

  24. sum a b c = a + b + c
    (sum 1 2 3)
    (((sum 1) 2) 3)
    Currying
    Friday, September 21, 2012

    View Slide

  25. x = expensive(1)
    y = expensive(3)
    z = (sum x)
    ((z 2) y)
    Friday, September 21, 2012

    View Slide

  26. x = expensive(1)
    y = expensive(3)
    z = (sum x)
    ((z 2) y)
    Compiler
    Friday, September 21, 2012

    View Slide

  27. x = expensive(1)
    y = expensive(3)
    z = (sum x)
    ((z 2) y)
    Compiler
    (sum expensive(1) 2 expensive(3))
    Friday, September 21, 2012

    View Slide

  28. CONCURRENCY ON
    LET’S TURN
    Friday, September 21, 2012

    View Slide

  29. state
    concurrency
    off
    on
    Friday, September 21, 2012

    View Slide

  30. Dataflow variables
    Painless concurrency!
    Friday, September 21, 2012

    View Slide

  31. lambda do |a, b|
    c = expensive_function.(a)
    d = also_expensive.(b)
    c + d
    end
    Friday, September 21, 2012

    View Slide

  32. lambda do |a, b|
    thread {
    c = expensive_function.(a)
    }
    thread {
    d = also_expensive.(b)
    }
    c + d
    end
    Friday, September 21, 2012

    View Slide

  33. main
    Friday, September 21, 2012

    View Slide

  34. main
    spawn thread 1
    Friday, September 21, 2012

    View Slide

  35. main
    spawn thread 1
    spawn thread 2
    Friday, September 21, 2012

    View Slide

  36. main
    spawn thread 1
    spawn thread 2
    unbound c
    Friday, September 21, 2012

    View Slide

  37. main
    spawn thread 1
    spawn thread 2
    unbound c
    defines c
    Friday, September 21, 2012

    View Slide

  38. main
    spawn thread 1
    spawn thread 2
    unbound c
    defines c
    unbound d
    Friday, September 21, 2012

    View Slide

  39. main
    spawn thread 1
    spawn thread 2
    unbound c
    defines c
    unbound d
    defines d
    Friday, September 21, 2012

    View Slide

  40. main
    spawn thread 1
    spawn thread 2
    unbound c
    defines c
    unbound d
    defines d
    c + d
    Friday, September 21, 2012

    View Slide

  41. STATE ON
    LET’S TURN
    Friday, September 21, 2012

    View Slide

  42. state
    concurrency
    on
    on
    Friday, September 21, 2012

    View Slide

  43. Friday, September 21, 2012

    View Slide

  44. PROBLEM
    THE
    Friday, September 21, 2012

    View Slide

  45. class Counter
    mattr_accessor :i
    self.i = 0
    end
    thread {
    Counter.i = Counter.i + 1
    }
    Friday, September 21, 2012

    View Slide

  46. thread 1 Counter.i thread 2
    Friday, September 21, 2012

    View Slide

  47. thread 1 Counter.i thread 2
    0
    Friday, September 21, 2012

    View Slide

  48. thread 1 Counter.i thread 2
    0
    0
    Friday, September 21, 2012

    View Slide

  49. thread 1 Counter.i thread 2
    0
    0
    1
    Friday, September 21, 2012

    View Slide

  50. thread 1 Counter.i thread 2
    0
    0
    1 1
    Friday, September 21, 2012

    View Slide

  51. thread 1 Counter.i thread 2
    0
    1
    0
    1 1
    Friday, September 21, 2012

    View Slide

  52. thread 1 Counter.i thread 2
    0
    1
    0
    1 1
    1
    Friday, September 21, 2012

    View Slide

  53. thread 1 Counter.i thread 2
    0
    1
    0
    1 1
    1
    1
    Friday, September 21, 2012

    View Slide

  54. thread 1 Counter.i thread 2
    0
    1
    0
    1 1
    1
    1
    1
    Friday, September 21, 2012

    View Slide

  55. thread 1 Counter.i thread 2
    0
    1
    0
    1 1
    1
    1
    1
    2
    Friday, September 21, 2012

    View Slide

  56. thread 1 Counter.i thread 2
    0
    1
    0
    1 1
    1
    1
    1
    2 2
    Friday, September 21, 2012

    View Slide

  57. thread 1 Counter.i thread 2
    0
    1
    0
    1 1
    1
    1
    1
    2 2
    2
    Friday, September 21, 2012

    View Slide

  58. thread 1 Counter.i thread 2
    0
    1
    0
    1 1
    1
    1
    1
    2 2
    2
    2
    Friday, September 21, 2012

    View Slide

  59. •shared-memory concurrent model
    •locks
    •transactional memory
    •message-passing concurrent model
    Friday, September 21, 2012

    View Slide

  60. •shared-memory concurrent model
    •locks
    •transactional memory
    •message-passing concurrent model
    Friday, September 21, 2012

    View Slide

  61. class Counter
    mattr_accessor :i
    self.i = 0
    end
    thread {
    Counter.i = Counter.i + 1
    }
    Friday, September 21, 2012

    View Slide

  62. class Counter
    mattr_accessor :i
    self.i = 0
    end
    thread {
    synchronize {
    Counter.i = Counter.i + 1
    }
    }
    Friday, September 21, 2012

    View Slide

  63. thread 1 Counter.i thread 2
    Friday, September 21, 2012

    View Slide

  64. thread 1 Counter.i thread 2
    0
    Friday, September 21, 2012

    View Slide

  65. thread 1 Counter.i thread 2
    0
    0
    Friday, September 21, 2012

    View Slide

  66. thread 1 Counter.i thread 2
    0
    0
    1
    Friday, September 21, 2012

    View Slide

  67. thread 1 Counter.i thread 2
    0
    0
    1 1
    Friday, September 21, 2012

    View Slide

  68. thread 1 Counter.i thread 2
    0
    1
    0
    1 1
    Friday, September 21, 2012

    View Slide

  69. thread 1 Counter.i thread 2
    0
    1
    0
    1 1
    1
    synchronize {
    Friday, September 21, 2012

    View Slide

  70. thread 1 Counter.i thread 2
    0
    1
    0
    1 1
    2
    1
    synchronize {
    Friday, September 21, 2012

    View Slide

  71. thread 1 Counter.i thread 2
    0
    1
    0
    1 1
    2
    1
    synchronize {
    2
    }
    Friday, September 21, 2012

    View Slide

  72. thread 1 Counter.i thread 2
    0
    1
    0
    1 1
    2
    2
    1
    synchronize {
    2
    }
    Friday, September 21, 2012

    View Slide

  73. thread 1 Counter.i thread 2
    0
    1
    0
    1 1
    2
    2
    2
    1
    synchronize {
    2
    }
    Friday, September 21, 2012

    View Slide

  74. thread 1 Counter.i thread 2
    0
    1
    0
    1 1
    2
    2
    3
    2
    1
    synchronize {
    2
    }
    Friday, September 21, 2012

    View Slide

  75. thread 1 Counter.i thread 2
    0
    1
    0
    1 1
    2
    2
    3 3
    2
    1
    synchronize {
    2
    }
    Friday, September 21, 2012

    View Slide

  76. +most popular approach
    +explicit control over the lock
    Friday, September 21, 2012

    View Slide

  77. - explicit control over the lock
    - pessimistic approach
    Friday, September 21, 2012

    View Slide

  78. •shared-memory concurrent model
    •locks
    •transactional memory
    •message-passing concurrent model
    Friday, September 21, 2012

    View Slide

  79. class Counter
    mattr_accessor :i
    self.i = ref { 0 }
    end
    thread {
    atomic {
    Counter.i = Counter.i + 1
    }
    }
    Friday, September 21, 2012

    View Slide

  80. thread 1 Counter.i thread 2
    Friday, September 21, 2012

    View Slide

  81. thread 1 Counter.i thread 2
    0
    Friday, September 21, 2012

    View Slide

  82. thread 1 Counter.i thread 2
    0
    0
    Friday, September 21, 2012

    View Slide

  83. thread 1 Counter.i thread 2
    0
    0
    1
    Friday, September 21, 2012

    View Slide

  84. thread 1 Counter.i thread 2
    0
    0
    1 1
    Friday, September 21, 2012

    View Slide

  85. thread 1 Counter.i thread 2
    0
    1
    0
    1 1
    Friday, September 21, 2012

    View Slide

  86. thread 1 Counter.i thread 2
    0
    1
    0
    1 1
    1
    atomic {
    Friday, September 21, 2012

    View Slide

  87. thread 1 Counter.i thread 2
    0
    1
    0
    1 1
    1
    1
    atomic {
    Friday, September 21, 2012

    View Slide

  88. thread 1 Counter.i thread 2
    0
    1
    0
    1 1
    1
    1
    1
    atomic {
    Friday, September 21, 2012

    View Slide

  89. thread 1 Counter.i thread 2
    0
    1
    0
    1 1
    1
    1
    2
    1
    atomic {
    Friday, September 21, 2012

    View Slide

  90. thread 1 Counter.i thread 2
    0
    1
    0
    1 1
    1
    1
    2 2
    1
    atomic {
    Friday, September 21, 2012

    View Slide

  91. thread 1 Counter.i thread 2
    0
    1
    0
    1 1
    1
    1
    2 2
    2
    1
    atomic {
    Friday, September 21, 2012

    View Slide

  92. thread 1 Counter.i thread 2
    0
    1
    0
    1 1
    1
    1
    2 2
    2
    1
    atomic {
    }
    Friday, September 21, 2012

    View Slide

  93. thread 1 Counter.i thread 2
    0
    1
    0
    1 1
    1
    1
    2 2
    2
    1
    atomic {
    }
    Friday, September 21, 2012

    View Slide

  94. thread 1 Counter.i thread 2
    0
    1
    0
    1 1
    1
    1
    2 2
    2
    1
    atomic {
    }
    Friday, September 21, 2012

    View Slide

  95. thread 1 Counter.i thread 2
    0
    1
    0
    1 1
    1
    1
    2 2
    2
    2
    1
    atomic {
    }
    Friday, September 21, 2012

    View Slide

  96. thread 1 Counter.i thread 2
    0
    1
    0
    1 1
    1
    1
    2 2
    2
    2 2
    1
    atomic {
    }
    Friday, September 21, 2012

    View Slide

  97. thread 1 Counter.i thread 2
    0
    1
    0
    1 1
    1
    1
    2 2
    2
    2 2
    3
    1
    atomic {
    }
    Friday, September 21, 2012

    View Slide

  98. thread 1 Counter.i thread 2
    0
    1
    0
    1 1
    1
    1
    2 2
    2
    2 2
    3
    3
    1
    atomic {
    }
    Friday, September 21, 2012

    View Slide

  99. + optimistic approach
    + no deadlock or race conditions
    Friday, September 21, 2012

    View Slide

  100. - potential unnecessary retries
    - transaction overhead
    Friday, September 21, 2012

    View Slide

  101. •shared-memory concurrent model
    •locks
    •transactional memory
    •message-passing concurrent model
    Friday, September 21, 2012

    View Slide

  102. server = lambda do |i|
    receive
    when :increment
    server.(i+1)
    when :check
    client <- i
    server.(i)
    else
    warn "unknown message"
    server.(i)
    end
    end
    server.(0)
    Friday, September 21, 2012

    View Slide

  103. thread {
    server <- :increment
    }
    Friday, September 21, 2012

    View Slide

  104. thread 1 server thread 2
    Friday, September 21, 2012

    View Slide

  105. thread 1 server thread 2
    0
    Friday, September 21, 2012

    View Slide

  106. thread 1 server thread 2
    0
    :increment
    Friday, September 21, 2012

    View Slide

  107. thread 1 server thread 2
    0
    1
    :increment
    Friday, September 21, 2012

    View Slide

  108. thread 1 server thread 2
    0
    1
    :increment
    :increment
    Friday, September 21, 2012

    View Slide

  109. thread 1 server thread 2
    0
    2
    1
    :increment
    :increment
    Friday, September 21, 2012

    View Slide

  110. thread 1 server thread 2
    0
    2
    1
    :increment
    :increment
    :increment
    Friday, September 21, 2012

    View Slide

  111. thread 1 server thread 2
    0
    2
    1
    3
    :increment
    :increment
    :increment
    Friday, September 21, 2012

    View Slide

  112. thread 1 server thread 2
    0
    2
    1
    3
    :increment
    :increment
    :increment
    :check
    Friday, September 21, 2012

    View Slide

  113. thread 1 server thread 2
    0
    2
    1
    3
    3
    :increment
    :increment
    :increment
    :check
    Friday, September 21, 2012

    View Slide

  114. thread 1 server thread 2
    0
    2
    1
    3
    3
    :increment
    :increment
    :increment
    :check
    Friday, September 21, 2012

    View Slide

  115. thread 1 server thread 2
    0
    2
    1
    3
    3
    3
    :increment
    :increment
    :increment
    :check
    Friday, September 21, 2012

    View Slide

  116. “Do not communicate by
    sharing memory;
    instead, share memory
    by communicating;”
    Effective Go
    Friday, September 21, 2012

    View Slide

  117. +no need for synchronization
    +easy to distribute (location
    transparency)
    Friday, September 21, 2012

    View Slide

  118. - coordination may be tricky
    - non-conventional approach
    Friday, September 21, 2012

    View Slide

  119. UP
    SUMMING
    Friday, September 21, 2012

    View Slide

  120. message-passing
    locks
    stm
    go, erlang
    ruby
    clojure
    dataflow oz
    Friday, September 21, 2012

    View Slide

  121. github.com/celluloid
    Friday, September 21, 2012

    View Slide

  122. @elixirlang / elixir-lang.org
    Friday, September 21, 2012

    View Slide

  123. MATTER
    DEFAULTS
    Friday, September 21, 2012

    View Slide

  124. Erlang and Clojure
    defaults to immutable
    Friday, September 21, 2012

    View Slide

  125. MAGIC BULLET
    THERE IS NO
    Friday, September 21, 2012

    View Slide

  126. REFERENCES
    Seven languages in seven weeks
    Friday, September 21, 2012

    View Slide

  127. REFERENCES
    Concepts, Techniques and Models
    of Computer Programming
    Friday, September 21, 2012

    View Slide

  128. REFERENCES
    Software Transactional Memory
    http://java.ociweb.com/mark/stm/article.html
    Persistent Data Structures
    http://www.infoq.com/presentations/Value-Identity-State-Rich-Hickey
    Friday, September 21, 2012

    View Slide

  129. ?
    QUESTIONS
    @josevalim
    Friday, September 21, 2012

    View Slide