Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Vamos falar de Concorrência
Search
Plataformatec
August 31, 2012
Programming
3
25k
Vamos falar de Concorrência
Por José Valim, na RubyConf Brasil 2012.
Plataformatec
August 31, 2012
Tweet
Share
More Decks by Plataformatec
See All by Plataformatec
O case da Plataformatec com o Elixir - Como uma empresa brasileira criou uma linguagem que é usada no mundo inteiro @ Elixir Brasil 2019
plataformatec
5
770
O case da Plataformatec com o Elixir - Como uma empresa brasileira criou uma linguagem que é usada no mundo inteiro @ QCon SP 2018
plataformatec
1
210
Elixir @ iMasters Intercon 2016
plataformatec
1
240
GenStage and Flow by @josevalim at ElixirConf
plataformatec
17
2.6k
Elixir: Programação Funcional e Pragmática @ 2º Tech Day Curitiba
plataformatec
2
200
Elixir: Programação Funcional e Pragmática @ Encontro Locaweb 2016
plataformatec
4
220
What's ahead for Elixir: v1.2 and GenRouter
plataformatec
15
1.8k
Arquiteturas Comuns de Apps Rails @ RubyConf BR 2015
plataformatec
6
360
Pirâmide de testes, escrevendo testes com qualidade @ RubyConf 2015
plataformatec
10
2.1k
Other Decks in Programming
See All in Programming
脱・初心者!脱・マネコン!AWS CDKを使ってみませんか!?
har1101
0
180
生成 AI の中身を覗いてみよう〜基礎から医療現場での応用まで〜
soh9834
2
770
IntelliJ IDEA を知らなかった 自分に教えたい小ネタ集 / IntelliJ IDEA Hints for My Past Self
mackey0225
3
180
GitHub Copilot Tips and Tricks
yuichielectric
26
7.5k
WinUI 3デモ - "CommunityToolkit.Mvvm"NuGetパッケージ編
andrewkeepcoding
0
140
WebComponentsで フレームワークを1ページに共存させる
webuilder240
0
150
DDDはなぜ難しいのか / 良いコードの定義と設計能力の壁
pospome
25
7.6k
Open Source Swift Workshop - Foundation and first party libraries
ikesyo
0
270
htmx is fun!
codehex
2
190
document.write再考
brn
5
2.5k
Some Quick Ideas To Improve Your Tests ( #jassttokyo )
teyamagu
PRO
2
2.3k
チームでモデリングを育てるうえで 考えたこと・気づいたこと / Cultivating Modeling in Teams: Thoughts and Insights
mackey0225
5
2.4k
Featured
See All Featured
Mobile First: as difficult as doing things right
swwweet
215
8.5k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
219
21k
Web development in the modern age
philhawksworth
201
10k
Why Our Code Smells
bkeepers
PRO
330
56k
Rails Girls Zürich Keynote
gr2m
91
13k
Building Adaptive Systems
keathley
29
1.8k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
113
18k
Fireside Chat
paigeccino
19
2.6k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
240
1.2M
Raft: Consensus for Rubyists
vanstee
130
6.2k
Code Reviewing Like a Champion
maltzj
512
39k
Debugging Ruby Performance
tmm1
68
11k
Transcript
CONCORRÊNCIA VAMOS FALAR SOBRE
None
Core Team Member
None
Executar duas ou mais tarefas de forma simultânea
Server Server Server Server
Server
MULTI CORE ÚNICO PROCESSO
estado concorrência off off
O modelo declarativo porque matemática rocks!
•não existe “mutação” •não existe concorrência •apenas funções
factorial = lambda do |x| case x when 0 1
else x * factorial.(x-1) end end print factorial.(10) # => 3628800
Determinismo As mesmas entradas => as mesmas saídas
•não existe random() •não existe I/O em disco •não existem
efeitos colaterais •sempre o mesmo resultado
lambda do |a, b| c = expensive_function.(a) d = also_expensive.(b)
c + d end
lambda do |a, b| c = expensive_function.(a) d = also_expensive.(b)
c + d end a = 1
lambda do |1, b| c = 42 d = also_expensive.(b)
c + d end
lambda do |a, b| c = expensive_function.(a) d = also_expensive.(b)
c + d end
lambda do |a, b| d = also_expensive.(b) c = expensive_function.(a)
c + d end
Haskell Usando determinismo para performance e expressividade
l = lambda { |a,b,c| a + b + c
} l.(1, 2, 3) #=> 6 l.curry #=> #<Proc> l.curry.(1) #=> #<Proc> l.curry.(1).(2).(3) #=> 6 Currying
l = lambda { |a,b| a * b } double
= l.curry.(2) triple = l.curry.(3) Currying
mult a b = a * b double = mult
2 (mult 2 3) ((mult 2) 3) Currying haskell
mult a b = a * b double = mult
2 double 3 haskell
mult a b = a * b double = mult
2 double 3 Compilador haskell
mult a b = a * b double = mult
2 double 3 Compilador (mult 2 3) haskell
CONCORRÊNCIA VAMOS ATIVAR
estado concorrência off on
Variáveis dataflow Concorrência sem dor!
lambda do |a, b| c = expensive_function.(a) d = also_expensive.(b)
c + d end
lambda do |a, b| thread { c = expensive_function.(a) }
thread { d = also_expensive.(b) } c + d end
main
main spawn thread 1
main spawn thread 1 spawn thread 2
main spawn thread 1 spawn thread 2 unbound c
main spawn thread 1 spawn thread 2 unbound c defines
c
main spawn thread 1 spawn thread 2 unbound c defines
c unbound d
main spawn thread 1 spawn thread 2 unbound c defines
c unbound d defines d
main spawn thread 1 spawn thread 2 unbound c defines
c unbound d defines d c + d
ESTADO VAMOS ATIVAR
estado concorrência on on
None
O PROBLEMA
class Counter mattr_accessor :i self.i = 0 end thread {
Counter.i = Counter.i + 1 }
thread 1 Counter.i thread 2
thread 1 Counter.i thread 2 0
thread 1 Counter.i thread 2 0 0
thread 1 Counter.i thread 2 0 0 1
thread 1 Counter.i thread 2 0 0 1 1
thread 1 Counter.i thread 2 0 1 0 1 1
thread 1 Counter.i thread 2 0 1 0 1 1
1
thread 1 Counter.i thread 2 0 1 0 1 1
1 1
thread 1 Counter.i thread 2 0 1 0 1 1
1 1 1
thread 1 Counter.i thread 2 0 1 0 1 1
1 1 1 2
thread 1 Counter.i thread 2 0 1 0 1 1
1 1 1 2 2
thread 1 Counter.i thread 2 0 1 0 1 1
1 1 1 2 2 2
thread 1 Counter.i thread 2 0 1 0 1 1
1 1 1 2 2 2 2
•shared-memory concurrent model •locks •transactional memory •message-passing concurrent model
•shared-memory concurrent model •locks •transactional memory •message-passing concurrent model
class Counter mattr_accessor :i self.i = 0 end thread {
Counter.i = Counter.i + 1 }
class Counter mattr_accessor :i self.i = 0 end thread {
synchronize { Counter.i = Counter.i + 1 } }
thread 1 Counter.i thread 2
thread 1 Counter.i thread 2 0
thread 1 Counter.i thread 2 0 0
thread 1 Counter.i thread 2 0 0 1
thread 1 Counter.i thread 2 0 0 1 1
thread 1 Counter.i thread 2 0 1 0 1 1
thread 1 Counter.i thread 2 0 1 0 1 1
1 synchronize {
thread 1 Counter.i thread 2 0 1 0 1 1
2 1 synchronize {
thread 1 Counter.i thread 2 0 1 0 1 1
2 1 synchronize { 2 }
thread 1 Counter.i thread 2 0 1 0 1 1
2 2 1 synchronize { 2 }
thread 1 Counter.i thread 2 0 1 0 1 1
2 2 2 1 synchronize { 2 }
thread 1 Counter.i thread 2 0 1 0 1 1
2 2 3 2 1 synchronize { 2 }
thread 1 Counter.i thread 2 0 1 0 1 1
2 2 3 3 2 1 synchronize { 2 }
+ técnica mais popular + controle explícito sobre o lock
- controle explícito sobre o lock - técnica pessimista
•shared-memory concurrent model •locks •transactional memory •message-passing concurrent model
class Counter mattr_accessor :i self.i = ref { 0 }
end thread { atomic { Counter.i = Counter.i + 1 } }
thread 1 Counter.i thread 2
thread 1 Counter.i thread 2 0
thread 1 Counter.i thread 2 0 0
thread 1 Counter.i thread 2 0 0 1
thread 1 Counter.i thread 2 0 0 1 1
thread 1 Counter.i thread 2 0 1 0 1 1
thread 1 Counter.i thread 2 0 1 0 1 1
1 atomic {
thread 1 Counter.i thread 2 0 1 0 1 1
1 1 atomic {
thread 1 Counter.i thread 2 0 1 0 1 1
1 1 1 atomic {
thread 1 Counter.i thread 2 0 1 0 1 1
1 1 2 1 atomic {
thread 1 Counter.i thread 2 0 1 0 1 1
1 1 2 2 1 atomic {
thread 1 Counter.i thread 2 0 1 0 1 1
1 1 2 2 2 1 atomic {
thread 1 Counter.i thread 2 0 1 0 1 1
1 1 2 2 2 1 atomic { }
thread 1 Counter.i thread 2 0 1 0 1 1
1 1 2 2 2 1 atomic { }
thread 1 Counter.i thread 2 0 1 0 1 1
1 1 2 2 2 1 atomic { }
thread 1 Counter.i thread 2 0 1 0 1 1
1 1 2 2 2 2 1 atomic { }
thread 1 Counter.i thread 2 0 1 0 1 1
1 1 2 2 2 2 2 1 atomic { }
thread 1 Counter.i thread 2 0 1 0 1 1
1 1 2 2 2 2 2 3 1 atomic { }
thread 1 Counter.i thread 2 0 1 0 1 1
1 1 2 2 2 2 2 3 3 1 atomic { }
+ técnica otimista + não possui deadlock nem condições de
corrida
- tentativas desnecessárias - overhead com transações
•shared-memory concurrent model •locks •transactional memory •message-passing concurrent model
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)
thread { server <- :increment }
client 1 server client 2
client 1 server client 2 0
client 1 server client 2 0 :increment
client 1 server client 2 0 1 :increment
client 1 server client 2 0 1 :increment :increment
client 1 server client 2 0 2 1 :increment :increment
client 1 server client 2 0 2 1 :increment :increment
:increment
client 1 server client 2 0 2 1 3 :increment
:increment :increment
client 1 server client 2 0 2 1 3 :increment
:increment :increment :check
client 1 server client 2 0 2 1 3 3
:increment :increment :increment :check
client 1 server client 2 0 2 1 3 3
:increment :increment :increment :check
client 1 server client 2 0 2 1 3 3
3 :increment :increment :increment :check
“Do not communicate by sharing memory; instead, share memory by
communicating;” Effective Go
+ não precisa de sincronização + fácil de distribuir
- coordenação é difícil - modelagem não convencional
RESUMINDO
message-passing locks stm go, erlang ruby clojure dataflow oz
github.com/celluloid
@elixirlang / elixir-lang.org
É IMPORTANTE O COMPORTAMENTO DEFAULT
BALAS DE PRATA NÃO EXISTEM
REFERÊNCIAS Seven languages in seven weeks
Concepts, Techniques and Models of Computer Programming REFERÊNCIAS
REFERÊNCIAS Software Transactional Memory http://java.ociweb.com/mark/stm/article.html Persistent Data Structures http://www.infoq.com/presentations/Value-Identity-State-Rich-Hickey
http://plataformatec.com.br Estamos contratando!
None
? PERGUNTAS José Valim @josevalim