25. Racecondition
Occurs when two or more threads can access shared
data and try to change it at the same time. Because
the thread scheduling algorithm can swap between
threads at any time, you don't know the order in which
the threads will attempt to access the shared data.
2525
34. Facts
1. MRI allows concurrency but prevents parallelism
2. Every Ruby process and process fork has its own GIL
3. MRI releases GIL when thread hits blocking IO (HTTP
request, console IO, etc.). Therefore, blocking IO could
run in parallel
4. Other implementations (JRuby) don't have GIL
3434
35. ReasonsofGIL
1. Protect Ruby internal C code from race conditions (it is
not always thread safe)
2. Protect calls to C extensions API
3. Protect developers from race conditions
3535
43. Example: Order a product
Order = Struct.new(:amount, :status) 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? # check
order.collect_payment # set
end
end
end.each(&:join)
4343
45. Mutex
Mutual exclusion, guarantees that no two threads enter
the critical section of code at the same time
Until the owning thread unlocks the mutex, no other
thread can lock it
The guarantee comes from the OS
4545
46. Mutextips
Use mutex to read value.
Remember: mutexes prevents parallel execution of
critical sections.
Make critical sections as small as possible.
Deadlock may occur when one thread waiting for a
mutex locked by another thread waiting itself for the
first one. Use mutex#try_lock
4646