- software complexo X - execução lenta; Y - software complexo/em escala X - metaprogramação em runtime; Y - software complexo X - ausência de concorrência; Y - software complexo
duas tarefas que se completarão em períodos que se sobrepõem. Isso não significa que as duas tarefas vão executar ao mesmo tempo — isso aí é paralelismo. Você pode ter concorrência até em máquinas single-threaded.
TEM concorrência — tem uma classe Thread, afinal. Mas é justamente aí onde a trava global do interpretador do Matz, a GIL, atrapalha a história de concorrência no Ruby. Você pode ter concorrência, mas não paralelismo (com a exceção do IO).
ruby-core) consideram a GIL uma funcionalidade fofa dessas, que reduz certas classes de bugs clássicos de threading. Mas olha o custo: meu código roda, mas roda lento, não aproveita a máquina.
contextos de execução que ficam subordinados a um processo do SO. Eles dividem o mesmo espaço de memória, ao contrário de processos; - Cada Thread pode, potencialmente, ser executado em paralelo pelo seu SO - A troca de contexto entre Threads é mais rápida do que em Processos
objetivos. Threads têm como vantagens consumir menos recursos e dividir o mesmo espaço de memória. Processos não exigem que você mude seu jeito de programar significativamente.
do def pending? status == 'pending' end ! def collect_payment puts "Collecting payment..." self.status = 'paid' end end ! order = Order.new(100.00, 'pending') ! 5.times.map do Thread.new do if order.pending? order.collect_payment end end end.each(&:join) Vamos usar um programinha que coleta pagamentos de pedidos.
shared_data << nil end end end.map(&:join) ! puts shared_data.size require "thread" ! shared_data = [] mutex = Mutex.new ! 10.times.map do Thread.new do 1000.times do mutex.synchronize { shared_data << nil } end end end.map(&:join) ! puts shared_data.size Sem Mutex Com Mutex
ConcurrencyError: Detected invalid array contents due to unsynchronized modifications with concurrent users << at org/jruby/RubyArray.java:1147 (root) at array_append_no_mutex.rb:6 times at org/jruby/RubyFixnum.java:275 (root) at array_append_no_mutex.rb:5 Sem Mutex O MRI dá a resposta que a gente espera, por conta da trava global do interpretador. A JVM nem deixa isso rodar, esse despautério.
Clojure) Actors (Erlang, Akka, Celluloid) Três grandes ideias (não as únicas) e linguagens/bibliotecas em que elas estão proeminentemente implementadas.
computacional para um mundo em que computadores teriam dezenas, centenas, milhares de unidades de processamento independentes. Há 41 anos eles sabiam claramente daquilo que nós aqui no Ruby tentamos ignorar.
maneira, o recipiente não sabe nada sobre quem mandou a mensagem: só interessa a mensagem em si. Esse desacoplamento entre as partes é uma ideia extremamente poderosa.
on Rails. ! It makes it a lot easier to get right prototypes and get them done quickly and not spend a lot of time debugging all this stuff in the standard library.” Em uma entrevista com o rubista Jesse Storimer, o criador do Celluloid, Tony Arcieri, disse que gosta de pensar que o Celluloid é uma espécie de Threads on Rails.
dá uma cara Ruby ao modelo de atores. Isso quer dizer que seu programa não vai ficar subitamente com outra cara, seguindo outros paradigmas, como quando se usa o EventMachine.
"Lost slice" end end Esta é a cara de um ator no Celluloid. A única coisa que precisa ser colocada é esse “include Celluloid”. A partir desse momento seu objeto é concorrente e está em seu próprio Thread.
model which combines method dispatch and thread synchronization. Each actor is a concurrent object running in its own thread, and every method invocation is wrapped in a fiber that can be suspended whenever it calls out to other actors, and resumed when the response is available. This means methods which are waiting for responses from other actors, external messages, or other system events (including I/O with Celluloid::IO) .