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
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
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
1.2k
O case da Plataformatec com o Elixir - Como uma empresa brasileira criou uma linguagem que é usada no mundo inteiro @ QCon SP 2018
plataformatec
1
240
Elixir @ iMasters Intercon 2016
plataformatec
1
270
GenStage and Flow by @josevalim at ElixirConf
plataformatec
17
2.9k
Elixir: Programação Funcional e Pragmática @ 2º Tech Day Curitiba
plataformatec
2
320
Elixir: Programação Funcional e Pragmática @ Encontro Locaweb 2016
plataformatec
4
310
What's ahead for Elixir: v1.2 and GenRouter
plataformatec
15
2.2k
Arquiteturas Comuns de Apps Rails @ RubyConf BR 2015
plataformatec
6
400
Pirâmide de testes, escrevendo testes com qualidade @ RubyConf 2015
plataformatec
10
2.5k
Other Decks in Programming
See All in Programming
なるべく楽してバックエンドに型をつけたい!(楽とは言ってない)
hibiki_cube
0
140
Amazon Bedrockを活用したRAGの品質管理パイプライン構築
tosuri13
5
770
OSSとなったswift-buildで Xcodeのビルドを差し替えられるため 自分でXcodeを直せる時代になっている ダイアモンド問題編
yimajo
3
620
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
600
Best-Practices-for-Cortex-Analyst-and-AI-Agent
ryotaroikeda
1
110
ノイジーネイバー問題を解決する 公平なキューイング
occhi
0
110
Package Management Learnings from Homebrew
mikemcquaid
0
230
Rust 製のコードエディタ “Zed” を使ってみた
nearme_tech
PRO
0
200
CSC307 Lecture 02
javiergs
PRO
1
780
Oxlintはいいぞ
yug1224
5
1.4k
CSC307 Lecture 04
javiergs
PRO
0
660
MUSUBIXとは
nahisaho
0
140
Featured
See All Featured
The Cult of Friendly URLs
andyhume
79
6.8k
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
61
52k
jQuery: Nuts, Bolts and Bling
dougneiner
65
8.4k
Chasing Engaging Ingredients in Design
codingconduct
0
110
Building Adaptive Systems
keathley
44
2.9k
Bash Introduction
62gerente
615
210k
Building Flexible Design Systems
yeseniaperezcruz
330
40k
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
260
Discover your Explorer Soul
emna__ayadi
2
1.1k
Ethics towards AI in product and experience design
skipperchong
2
200
Making Projects Easy
brettharned
120
6.6k
Navigating Team Friction
lara
192
16k
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