“Fukumoto Atsushi” fukumoto@imasy.or.jp schrieb im Newsbeitrag
news:200303241306.WAA05221@hawk.wings.imasy.or.jp…
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.
This might well be, but when it does the implementation of Mutex will
likely change to benefit from multiprocessor support.
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.
I wasn’t aware of this nature of the library implementation of Queue and
of the internals of Mutex. I thought, Mutex is so basic that it is
implemented native, which likely would have decreased the performance
penalty. I guess, this might change, if ruby once supports native
threads. So, since this is a class provided with the installation it is
reasonable to use it, I guess.
From a pragmatic perspective it’s all too reasonable to provide a thread
safe queue implementation since this is something many will need. Still
it feels a bit odd to view Mutex and Queue on the same level of
granularity. I view a Mutex as a basic building block with which I can
realize a thread safe queue. So for me these have different
granularities…
While we’re at it, let me suggest to provide a block version of
Thread.critical that switches it on before the block and off after. At
least my version 1.6.7 does not seem to include it.
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:
Interesting. If I find the time I’ll benchmark my Queue version agains
this, too.
Thanks for sharing these insights!
robert