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
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
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
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
600
ぼくの開発環境2026
yuzneri
0
240
カスタマーサクセス業務を変革したヘルススコアの実現と学び
_hummer0724
0
730
CSC307 Lecture 01
javiergs
PRO
0
690
AI Agent の開発と運用を支える Durable Execution #AgentsInProd
izumin5210
7
2.3k
HTTPプロトコル正しく理解していますか? 〜かわいい猫と共に学ぼう。ฅ^•ω•^ฅ ニャ〜
hekuchan
2
690
Honoを使ったリモートMCPサーバでAIツールとの連携を加速させる!
tosuri13
1
180
Vibe Coding - AI 驅動的軟體開發
mickyp100
0
180
Package Management Learnings from Homebrew
mikemcquaid
0
230
Fluid Templating in TYPO3 14
s2b
0
130
AI時代の認知負荷との向き合い方
optfit
0
160
CSC307 Lecture 08
javiergs
PRO
0
670
Featured
See All Featured
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.1k
Fashionably flexible responsive web design (full day workshop)
malarkey
408
66k
The World Runs on Bad Software
bkeepers
PRO
72
12k
Reflections from 52 weeks, 52 projects
jeffersonlam
356
21k
Pawsitive SEO: Lessons from My Dog (and Many Mistakes) on Thriving as a Consultant in the Age of AI
davidcarrasco
0
67
Neural Spatial Audio Processing for Sound Field Analysis and Control
skoyamalab
0
170
Mobile First: as difficult as doing things right
swwweet
225
10k
[RailsConf 2023] Rails as a piece of cake
palkan
59
6.3k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.3k
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
240
Being A Developer After 40
akosma
91
590k
Measuring & Analyzing Core Web Vitals
bluesmoon
9
760
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