Marcus
Marcus

Reputation: 5255

What's the correct Ruby pattern for waiting for a background thread to start?

I need to write a Ruby program that executes a background program, and performs some functionality on it.

Before doing any operation, the main thread needs to make sure that the background thread is started. What the correct pattern?

This is not exact:

condition = ConditionVariable.new
mutex = Mutex.new

thread = Thread.new do
  mutex.synchronize  { condition.signal }
  # background work
end

mutex.synchronize { condition.wait(mutex) }
# other work

because :signal could execute before :wait, blocking the main thread.

An exact solution is:

thread = Thread.new do
  Thread.current[:started] = true
  # background work
end

sleep 0.01 while thread[:started].nil?
# other work

however, it uses sleep, which I'd like to avoid.

Another exact, but more complex, solution is:

mutex = Mutex.new
condition = ConditionVariable.new

thread = Thread.new do
  mutex.synchronize do
    Thread.current[:started] = true
    condition.signal
  end
  # background work
end

mutex.synchronize do
  condition.wait(mutex) if !thread[:started]
end

# other work

Is there any exact, simple and idiomatic way to structure this functionality?

Upvotes: 0

Views: 223

Answers (1)

Stefan
Stefan

Reputation: 114248

You could use a Queue:

queue = Queue.new

thread = Thread.new do
  queue.push :ready
  # background work
end

queue.pop
# other work

Queue#pop will wait until an item is available and return it.

Upvotes: 1

Related Questions