Avoiding busy waiting

I have a situation where I’d like to set up a queue that’s filled by one
thread and read by another thread. However, I don’t want the consumer thread
to busy-wait when the queue is empty, to avoid chewing the CPU.

My original thought was to use a ConditionVariable. Ie, when the consumer
thread finds that the length of the queue is currently zero it then does a
wait on a ConditionVariable, using the mutex that’s guarding the queue.

But, how does the producer thread know for certain that it needs to signal the
condition variable?

You could do the signal only when the size of the queue is zero just before
you append a new entry, but the fact that it’s empty doesn’t mean someone’s
actually waiting for it to become non-empty.

The consumer thread could currently be processing the last entry it retrieved
and by the time it gets back, the new entry may already be there, hence it
wouldn’t do the wait.

I note that the documentation in PR says that ConditionVariable.signal() wakes
up the first thread in line waiting for the lock. Does that mean that if
noone is waiting, the signal just gets thrown away? In that case, things may
be OK.

Anyway, I guess you get the picture. Is there a clean way to handle this
situation? Maybe there’s a library or class I’m not aware of that provides
this kind of blocking queue.

Thanks in advance,

Harry O.

I note that the documentation in PR says that
ConditionVariable.signal() wakes up the first thread in line waiting
for the lock. Does that mean that if noone is waiting, the signal
just gets thrown away? In that case, things may be OK.

Yes, ConditionVariable#signal just dequeues a thread waiting on the
ConditionVariable and awakes it.

See thread.rb. `t.run if t’ means that.

Anyway, I guess you get the picture. Is there a clean way to handle this
situation? Maybe there’s a library or class I’m not aware of that provides
this kind of blocking queue.

And then see thread.rb again. There’s Queue and SizedQueue which
implements synchronized queue.

Actually I’ve not used Thread more than toy examples, but I believe

logically it works unless a bug exists.

···

In message 200209221747.22910.harryo@zip.com.au harryo@zip.com.au writes:


kjana@dm4lab.to September 23, 2002
He knows most who speaks least.

My original thought was to use a ConditionVariable. Ie, when the consumer
thread finds that the length of the queue is currently zero it then does a
wait on a ConditionVariable, using the mutex that’s guarding the queue.

The solution I saw in
Concurrent Programming
C. R. Snow
Cambridge University Press, 1992
ISBN: 0521327962
used two condition variables, basically: read_to_read, and
read_to_write. I’ve seen it elsewhere too.

Thanks in advance,

Harry O.

    Hugh
···

On Sun, 22 Sep 2002, Harry Ohlsen wrote:

Thanks; the Queue class was precisely what I needed! I’m surprised I’ve not
noticed it in any of the documentation before.

Harry O.

···

On Mon, 23 Sep 2002 01:30, you wrote:

In message 200209221747.22910.harryo@zip.com.au

And then see thread.rb again. There’s Queue and SizedQueue which
implements synchronized queue.

Actually I’ve not used Thread more than toy examples, but I believe

logically it works unless a bug exists.

Thanks; the Queue class was precisely what I needed! I’m surprised I’ve
not
noticed it in any of the documentation before.

I don’t think it’s in the Pickaxe. It is in TRW.

Hal

···

----- Original Message -----
From: “Harry Ohlsen” harryo@zip.com.au
To: “ruby-talk ML” ruby-talk@ruby-lang.org
Sent: Sunday, September 22, 2002 4:25 PM
Subject: Re: Avoiding busy waiting