I was experimenting with multithreading examples. I am trying to produce a race condition using the following code. But I am always getting the same (correct) output.
class Counter
attr_reader :count
def initialize
@count = 0
end
def increment
@count += 1
end
def decrement
@count -= 1
end
end
c = Counter.new
t1 = Thread.start { 100_0000.times { c.increment } }
t2 = Thread.start { 100_0000.times { c.increment } }
t1.join
t2.join
p c.count #200_0000
I am able to observe the race condition in Java using much less number of iterations in each thread. Is it that I am not running it enough number of times to produce a race condition, or +
/-
are Thread safe in Ruby? I am using ruby 2.0.0p247
Yes, we can have race conditions in Node. js!
Race conditions are most commonly associated with computer science and programming. They occur when two computer program processes, or threads, attempt to access the same resource at the same time and cause problems in the system. Race conditions are considered a common issue for multithreaded applications.
This is because MRI Ruby threads are not really parallel due to GIL (see here), at CPU level they are executed one at a time.
Each command in a thread is executed one at a time hence @count
in each thread is always updated correctly.
Race condition can be simulated by adding another variable like:
class Counter
attr_accessor :count, :tmp
def initialize
@count = 0
@tmp = 0
end
def increment
@count += 1
end
end
c = Counter.new
t1 = Thread.start { 1000000.times { c.increment; c.tmp += 1 if c.count.even?; } }
t2 = Thread.start { 1000000.times { c.increment; c.tmp += 1 if c.count.even?; } }
t1.join
t2.join
p c.count #200_0000
p c.tmp # not 100_000, different every time
A nice example of race condition is given here, copied below for completeness
class Sheep
def initialize
@shorn = false
end
def shorn?
@shorn
end
def shear!
puts "shearing..."
@shorn = true
end
end
sheep = Sheep.new
5.times.map do
Thread.new do
unless sheep.shorn?
sheep.shear!
end
end
end.each(&:join)
Here's the result I see from running this on MRI 2.0 several times.
$ ruby check_then_set.rb => shearing...
$ ruby check_then_set.rb => shearing... shearing...
$ ruby check_then_set.rb => shearing... shearing...
Sometimes the same sheep is being shorn twice!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With