Are YARV Arrays' push/pop methods thread-safe?

372 Views Asked by At

Suppose I have a pair of (producer, consumer) YARV threads (Tp,Tc) sharing an Array q - Tp pushes to q, and Tc pops from it. If the order in which the pushes and pops get executed is unimportant, does the code work without any synchronization mechanism?

1

There are 1 best solutions below

2
On BEST ANSWER

Accessing arrays is thread-safe in MRI/YARV (and only there) most of the time due to its global interpreter lock (GIL), thus mostly by accident.

You still would have to make sure that you are only performing a single operation each time and avoid read/write constructs. In other Ruby implementations like Rubinius or JRuby, Arrays are explicitly not thread safe.

With that being said, Ruby ships with a different primitive for inter-thread communication, which co-incidentaly is about the only class in MRI/VARV which is explicitly thread-safe: the Queue. It supports pushing and poping objects in a thread-safe way.

Take this example from Ruby's documentation:

queue = Queue.new

producer = Thread.new do
  5.times do |i|
     sleep rand(i) # simulate expense
     queue << i
     puts "#{i} produced"
  end
end

consumer = Thread.new do
  5.times do |i|
     value = queue.pop
     sleep rand(i/2) # simulate expense
     puts "consumed #{value}"
  end
end

There also exists a well-maintained project called concurrent-ruby which offers a lot of powerful primitives for concurrent programming across threads.