uno_ordinary
uno_ordinary

Reputation: 458

Ruby multithreading queues

I have a problem with synchronizing threads, I have no idea how to do it, can someone help me ?

So, the thing is that I have to launch the threads in some specific order. The order is the following:

Threads 1 and 7 can go simultaneously, and after one of them is finished, the next thread is launched (i.e. thread 2 or/and thread 6), the same way goes with thread 3 and 5. And the last one, after both thread 3 and 5 are finished running, goes the last one, thread 4.

This is the code, I had begun with, but I am stuck at the queue implementation somehow.

MUTEX          = Mutex.new
high_condition = ConditionVariable.new
low_condition  = ConditionVariable.new
threads = []

7.times do |i|
  threads << Thread.new{
    MUTEX.synchronize {
      Thread.current["number"] = i

      you_shall_not_pass
    }
  }
end

threads.map(&:join)

def you_shall_not_pass
  order = Thread.current["number"]
end

Upvotes: 1

Views: 351

Answers (1)

Kristj&#225;n
Kristj&#225;n

Reputation: 18803

Use Ruby's Queue as a counting semaphore. It has blocking push and pop operations that you can use to hand out a limited number of tokens to threads, requiring that each thread acquire a token before it runs and release the token when it's finished. If you initialize the queue with 2 tokens, you can ensure only 2 threads run at a time, and you can create your threads in whatever order you like.

require 'thread'

semaphore = Queue.new
2.times { semaphore.push(1) } # Add two concurrency tokens

puts "#{semaphore.size} available tokens"

threads = []
[1, 7, 2, 6, 3, 5, 4].each do |i|
  puts "Enqueueing thread #{i}"
  threads << Thread.new do
    semaphore.pop # Acquire token
    puts "#{Time.now} Thread #{i} running. #{semaphore.size} available tokens. #{semaphore.num_waiting} threads waiting."
    sleep(rand(10)) # Simulate work
    semaphore.push(1) # Release token
  end
end

threads.each(&:join)

puts "#{semaphore.size} available tokens"
$ ruby counting_semaphore.rb
2 available tokens
Enqueueing thread 1
Enqueueing thread 7
2015-12-04 08:17:11 -0800 Thread 7 running. 1 available tokens. 0 threads waiting.
2015-12-04 08:17:11 -0800 Thread 1 running. 0 available tokens. 0 threads waiting.
Enqueueing thread 2
Enqueueing thread 6
2015-12-04 08:17:11 -0800 Thread 2 running. 0 available tokens. 0 threads waiting.
Enqueueing thread 3
Enqueueing thread 5
Enqueueing thread 4
2015-12-04 08:17:19 -0800 Thread 6 running. 0 available tokens. 3 threads waiting.
2015-12-04 08:17:19 -0800 Thread 5 running. 0 available tokens. 2 threads waiting.
2015-12-04 08:17:21 -0800 Thread 3 running. 0 available tokens. 1 threads waiting.
2015-12-04 08:17:22 -0800 Thread 4 running. 0 available tokens. 0 threads waiting.
2 available tokens

Upvotes: 1

Related Questions