Does ruby 3.3 have an implicit mutex synchronization?
so I have a code example like this
counters = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
threads = do
do
100000.times do
counters.map! { |counter| counter + 1 }
end
end
end
threads.each(&:join)
puts counters.to_s5.times.mapThread.new
when I run this code in ruby 3.3 I always get
[500000, 500000, 500000, 500000, 500000, 500000, 500000, 500000, 500000, 500000]
but if I ran same code in ruby less than 3.3 so ruby 3.2, 3.1, 2.7
I don't get the right result
[500000, 500000, 500000, 500000, 500000, 500000, 400000, 500000, 500000, 500000]
to get the right result I have to use mutex.
so my question is what changed in ruby 3.3?
BTW I was following this article https://vaneyckt.io/posts/ruby_concurrency_in_praise_of_the_mutex/ and on ruby 3.3 atomicity.rb and visibility.rb both works fine without mutex(it like ruby 3.3 have some implicit mutex built-in)
BTW I've tested on 2 different machines
- MacBook Pro M1 Pro running MacOS
- MacBook Pro 16 2019 Intel running Ubuntu 22.04
Edit: if I add an extra zero then it breaks the functionality even on ruby 3.3. so there is no implicit mutex and there some optimization in the ruby 3.3 that was creating an illusion of implicit mutex when thread have very little data to work on.