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
990
O case da Plataformatec com o Elixir - Como uma empresa brasileira criou uma linguagem que é usada no mundo inteiro @ QCon SP 2018
plataformatec
1
220
Elixir @ iMasters Intercon 2016
plataformatec
1
260
GenStage and Flow by @josevalim at ElixirConf
plataformatec
17
2.7k
Elixir: Programação Funcional e Pragmática @ 2º Tech Day Curitiba
plataformatec
2
290
Elixir: Programação Funcional e Pragmática @ Encontro Locaweb 2016
plataformatec
4
280
What's ahead for Elixir: v1.2 and GenRouter
plataformatec
15
2k
Arquiteturas Comuns de Apps Rails @ RubyConf BR 2015
plataformatec
6
370
Pirâmide de testes, escrevendo testes com qualidade @ RubyConf 2015
plataformatec
10
2.3k
Other Decks in Programming
See All in Programming
PHPカンファレンス名古屋2025 タスク分解の試行錯誤〜レビュー負荷を下げるために〜
soichi
1
730
Formの複雑さに立ち向かう
bmthd
1
940
Datadog DBMでなにができる? JDDUG Meetup#7
nealle
0
150
機能が複雑化しても 頼りになる FactoryBotの話
tamikof
1
220
PEPCは何を変えようとしていたのか
ken7253
3
290
複数のAWSアカウントから横断で 利用する Lambda Authorizer の作り方
tc3jp
0
120
CloudNativePGを布教したい
nnaka2992
0
120
Honoをフロントエンドで使う 3つのやり方
yusukebe
7
3.6k
kintone開発を効率化するためにチームで試した施策とその結果を大放出!
oguemon
0
170
Better Code Design in PHP
afilina
0
180
お前もAI鬼にならないか?👹Bolt & Cursor & Supabase & Vercelで人間をやめるぞ、ジョジョー!👺
taishiyade
7
4.2k
Domain-Driven Design (Tutorial)
hschwentner
13
22k
Featured
See All Featured
Stop Working from a Prison Cell
hatefulcrawdad
268
20k
How to Think Like a Performance Engineer
csswizardry
22
1.4k
Why Our Code Smells
bkeepers
PRO
336
57k
Adopting Sorbet at Scale
ufuk
75
9.2k
Fashionably flexible responsive web design (full day workshop)
malarkey
406
66k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
46
2.3k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
160
15k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
114
51k
GraphQLとの向き合い方2022年版
quramy
44
14k
Optimizing for Happiness
mojombo
377
70k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
7
650
The Straight Up "How To Draw Better" Workshop
denniskardys
232
140k
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