>> Pardon me, but I like to object that statement: writing a queue class
>> using mutex does indeed gain something. You get increased concurrency.
>> Thread.critical globally prevents all other threads from being executed
>> (with some restrictions for new threads, exceptions etc.), while my
>> implementation using a mutex does not prevent threads from running that do
>> not use the queue.

I don't understand why you think that way.  Mutex class in
lib/thread.rb uses Thread.critical, so does ConditionVariable, too.
Using both would be using twice more Thread.critical than Queue (three
times if you use ConditionVariable#broadcast).  Besides, increasing
concurrency has little meaning in current Ruby implementation since it
doesn't support mulitprocessors yet.


>> From a more fundamental and maybe theoretical point of view, the mutex is
>> the more appropriate means, because it is focused on queue usage and does
>> not have side effects on other threads running.  Thread.critical= OTOH can
>> be seen as acting on a single global mutex which makes immediately clear
>> that it results in less concurrency.  Even if that gives better
>> performance I would use the mutex approach as long as there is no need to
>> squeeze out the last bit of performance.

That's weird attitude.  For one, Mutex uses Thread.critical as much as
Queue does.  For two, using Queue will hide any reference to
Thread.critical as much as Mutex does.  For three, in Ruby library
world, Queue is as much a primitive as Mutex.  It is possible to
implement Mutex using Queue as much as you can implement Queue with
Mutex.


>> > (My experiment showed it's about ten times slower when
>> > written using Mutex.  Though some optimization may be possible.)
>> 
>> Out of curiosity: did you performance test your own queue implementation
>> or that found on the wiki at http://www.rubygarden.org/ruby?MultiThreading
>> ?  And how did you do the tests?

That was my own code, and I'm not sure yet where the performance
difference came from, so I'll be glad to hear others' experiences.  (I
had to resort to implement my own semaphore code for performance, now
registered in RAA.)  Benchmark method was something like:

require 'benchmark'
require 'pipe'
require 'threadutil'  # http://www.imasy.or.jp/~fukumoto/ruby/threadutil.rb

M = 10
N = 1000

def tst(q)
  senders = M.threads do N.times do |i| q.push(i) end end
  receivers = M.threads do N.times do |i| q.pop end end
  senders.join
  receivers.join
end

Benchmark::bm do |x|
  x.report { tst(Pipe.new) }
  x.report { tst(Queue.new) }
end


Cheers,


						FUKUMOTO Atsushi
						fukumoto / imasy.or.jp