Howto wait for multiple queues (Queue.py)?

Alex Martelli aleax at aleax.it
Thu Nov 21 06:43:33 EST 2002


Andreas Ames wrote:

> Alex Martelli <aleax at aleax.it> writes:
> 
>> ...this doesn't follow -- just make all requests to a thread onto
>> a single Queue (tag the requests with 'kind' or whatever as needed)
>> and live happily.  A Queue instance *IS* implicitly, automatically
>> and intrinsically "synchronized" -- several threads can be reading
>> and/or writing to the same Queue instance and you're guaranteed that
>> they'll never interfere with each other.  That's just about the
>> whole POINT of the Queue class.
> 
> Sorry, this confuses me a bit.  If you understood my mail such that I
> want to synchronize the access of several threads to one queue, my
> mail must have been totally ambiguous.
> 
> What I really want to achieve is that several threads can consume
> items from several (possibly identical) _sets_ of queues.  As I read
> the docs and looked at the source in Queue.py I don't doubt that this
> queue implementation is threadsave.

Why?  How would it advantage your application to have a thread peel
events off many queues rather than one?


> What I don't understand is the reasoning, *why* every thread should
> only have exactly one input queue.  This has several disadvantages

To avoid the complications that come from having many -- why else?

> from my point of view.  Several threads can't share the same input
> queue 

Of course they can, why shouldn't they?  You claim you understand
how Queue instances are threadsafe, so why would you think you
can't have several threads peeling events from the same Queue?

> and I can't distinguish between several input channels within
> one thread.  

But of course you can, it's trivial!  If it's too much bother to
have the posters of events tag them directly, wrap the one Queue
with as many wrapping-with-identification Channel instances as
you will, e.g.

class Channel:
    def __init__(self, identifier, queue):
        self.identifier = identifier
        self.queue = queue
    def put(self, whatever):
        self.queue.put((identifier, whatever))

there -- what's the problem?  It's quite easy to similarly
delegate put_nowait, get's, etc, etc, of course.


> For example in my case the threads should have input
> channels for commands and for events (such as command responses or
> unsolicited events).  Furthermore there can be different functional
> units which write commands and/or events to the same thread.  It is
> clear to me that this can be achieved by giving the different
> commands/events different types/kinds and use one input queue for all
> of them.  But I have at least two reservetions against this:
> 
> - The single input queue could be a bottleneck.  If you choose to
>   avoid the bottleneck by providing several threads which understand
>   the same commands, the producers have to decide about the
>   scheduling, i.e. which thread gets which command.

Not at all, the several working threads can perfectly well peel events
off the same queue.  That's quite a common arrangement, to have a
pool of threads all peeling work requests off the same queue.


> - It seems more intuitive to me to have different input channels for
>   different purposes.

So wrap the above Channel -- several instances thereof around the
one queue -- and let your intuition be happy.


> This is comparable to the 'select()' function which is widely used.

At low-levels, yes, but it's best wrapped in a more abstract
Reactor Pattern for practical use.  Twisted hinges on that, and
so do such frameworks as ACE.


> If you say, there is no good implementation for waiting on several
> queues in python, then ok, in this case I admit that using a single
> input queue per thread might be the way to go (I'm also not satisfied
> by the three alternatives I have enumerated in the original post; I
> think I will try alternative 3 for now).

There's no good implementation (that I know of), AND there is
absolutely no real need for it, so it's unlikely that anybody would
sweat to make such a "good implementation" happen -- why would they?


Alex




More information about the Python-list mailing list