I’m trying to “replicate” the behaviour of CUDA’s __synchtreads() function in Ruby. Specifically, I have a set of N threads that need to execute some code, then all wait on each other at mid-point in execution before continuing with the rest of their business. For example:
x = 0
a = Thread.new do
x = 1
syncthreads()
end
b = Thread.new do
syncthreads()
# x should have been changed
raise if x == 0
end
[a,b].each { |t| t.join }
What tools do I need to use to accomplish this? I tried using a global hash, and then sleeping until all the threads have set a flag indicating they’re done with the first part of the code. I couldn’t get it to work properly; it resulted in hangs and deadlock. I think I need to use a combination of Mutex and ConditionVariable but I am unsure as to why/how.
Edit: 50 views and no answer! Looks like a candidate for a bounty…
Let’s implement a synchronization barrier. It has to know the number of threads it will handle, n, up front. During first n – 1 calls to
syncthe barrier will cause a calling thread to wait. The call number n will wake all threads up.Whole body of
syncis a critical section, i.e. it cannot be executed by two threads concurrently. Hence the call toMutex#synchronize.When the decreased value of
@countis positive the thread is frozen. Passing the mutex as an argument to the call toConditionVariable#waitis critical to prevent deadlocks. It causes the mutex to be unlocked before freezing the thread.A simple experiment starts 1k threads and makes them add elements to an array. Firstly they add zeros, then they synchronize and add ones. The expected result is a sorted array with 2k elements, of which 1k are zeros and 1k are ones.
As a matter of fact, there’s a gem named barrier which does exactly what I described above.
On a final note, don’t use sleep for waiting in such circumstances. It’s called busy waiting and is considered a bad practice.