Quick Question about Queue's

I am putting together a small app that will need a message queue. There
will basically be 2 threads only accessing it (at most 3) and I was
wondering if there was a “best” Queue class to use.

I know there is one in thread.rb that comes with the ruby distrobution
but it uses critcal sections, which from reading Pickaxe can be dangerous.

I see there is another Queue class, this time using a mutex shown on
http://www.rubygarden.org/ruby?MultiThreading.

Which would be better to use? Does the thread critical one have less of
a performance hit?

Rob

I know there is one in thread.rb that comes with the ruby distrobution
but it uses critcal sections, which from reading Pickaxe can be dangerous.

Uh, you are confusing the problem. Critical sections are nature in
multi-thread programming. In Ruby, Queue class is as much a primitive
tool as Mutex class for inter-thread communication. Rewriting the
Queue class using Mutex gains nothing, and probably it will become
slower. (My experiment showed it’s about ten times slower when
written using Mutex. Though some optimization may be possible.)

					FUKUMOTO Atsushi
					fukumoto@imasy.or.jp

Uh, you are confusing the problem.

sigh thats always the way.

Thank you FUKUMOTO for clearing that up :slight_smile:

Critical sections are nature in
multi-thread programming. In Ruby, Queue class is as much a primitive
tool as Mutex class for inter-thread communication. Rewriting the
Queue class using Mutex gains nothing, and probably it will become
slower. (My experiment showed it’s about ten times slower when
written using Mutex. Though some optimization may be possible.)

Rob

“Fukumoto Atsushi” fukumoto@imasy.or.jp schrieb im Newsbeitrag
news:200303231418.XAA02902@hawk.wings.imasy.or.jp…

I know there is one in thread.rb that comes with the ruby
distrobution
but it uses critcal sections, which from reading Pickaxe can be
dangerous.

Uh, you are confusing the problem. Critical sections are nature in
multi-thread programming. In Ruby, Queue class is as much a primitive
tool as Mutex class for inter-thread communication. Rewriting the
Queue class using Mutex gains nothing, and probably it will become
slower.

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.

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.

(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?

Regards

robert

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

“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