Hello,

#*******************STARTCODE

start_time = Time.now
$count = 0
class Queue
  def initialize *s # splat operator allows variable length argument
list
    @mutex = Mutex.new
    @queue = []
    s.each { |e| @queue.push e }
  end

  def enq v
      @queue.push v
  end

  def deq
    @mutex.synchronize {item = @queue.shift}
  end

  def empty?
    @mutex.synchronize{@queue.length == 0}
  end

  def count
   @mutex.synchronize do
     $count += 1
   end
  end
end


#*****Test

queue = Queue.new
500.times do |a|
  queue.enq a
end
threads = []


# Create 5 threads which fetch values from the Q.
  5.times do
    threads << Thread.new {
    until queue.empty?
      queue.count
      puts "Thread ID: #{Thread.current}.Job  started"
      puts "#{queue.deq}"
      #sleep 0.0001
      puts "Thread ID: #{Thread.current}.Job  complete"
    end
   }
  end


threads.each {|t| t.join }
puts "Count"
puts $count
puts "timeTaken:"
puts Time.now - start_time

# *************CODE ENDS******************


I have five threads which fetch values from a queue. The above code
works perfectly well in case of a single thread. But the issue arises
when there are more threads.

In case of 5 threads the number of times the block is executed is 503
where it should have been 500.

I know the reason why?
The "deq" and "empty?" methods are not synchronized.
So when the final item is removed from the thread, other threads  access
the empty? method before the @queue.length becomes 0.

Hence the difference in count.

If the sleep is activated this problem is solved.

Any suggestion on how to get this working without the sleep?

Thanks.
-- 
Posted via http://www.ruby-forum.com/.