threads or queue for this task

James J. Besemer jb at cascade-sys.com
Mon Sep 16 14:50:16 EDT 2002


robin at execulink.com wrote:

>I may sometimes be clever, and can no doubt cobble together code from
>reading the docs (which I have been doing so far), but what I don't
>know are some of the trade-offs of using certain constructs, or the
>optimal way to do things. That is much more difficult to glean without
>actual code examples.
>
>For example, I really don't know what "proper design" I should use in
>this case. Any sample code?
>
The following illustrates my understanding of what you're trying to do.

    import thread
    import Queue

    # three queues connect four threads

    CmdQ1 = Queue.Queue()
    CmdQ2 = Queue.Queue()
    CmdQ3 = Queue.Queue()

    # Reader thread reads commands from stdin and
    # dispatches to appropriate thread via queue

    def Reader():
        while 1:
            line = stdin.readline()
            if not line:
                return

            if line[0] == '1':
                CmdQ1.put( line[1:])
            elif line[0] == '2':
                CmdQ2.put( line[1:])
            elif line[0] == '3':
                CmdQ3.put( line[1:])
            else:
                continue    # or signal error

    # Command threads process commands as they arrive via queue

    def Cmd1():
        while 1:
            cmd = CmdQ1.get()
            process1( cmd )

    def Cmd2():
        while 1:
            cmd = CmdQ2.get()
            process2( cmd )

    def Cmd3():
        while 1:
            cmd = CmdQ3.get()
            process3( cmd )

    def main():
       
        thread.start_new_thread( Cmd1, ())
        thread.start_new_thread( Cmd2, ())
        thread.start_new_thread( Cmd3, ())

        # reader thread runs in mainline
        Reader()


Frankly, it doesn't get any simpler than this.

With threads as nodes and Queues as pipes, you can create practically 
any data flow topology you wish.

>The interface to Queue is deceptively simple. Are there constructs to
>avoid or performance trade-offs to different methods? Again, any
>explicit code (or at least explicit help as to which methods are
>preferable) would be appreciated.
>

It's not deceptively simple.  It's merely simple.  Sometimes a Queue is 
simply a Queue.

>I am also put off by the description of the Queue Object, particularly
>methods like empty() which says: "Return 1 if the queue is empty, 0
>otherwise. Because of multithreading semantics, this is not reliable."
>

The answer is accurate when it is returned to you but due to the nature 
of multithreading semantics, the value also is subject to change without 
notice.  So if you read it and see a 0 or a 1, this is a true historical 
fact but you can't rely on the value being true at arbitrary points in 
the future so you can't really base any decisions on it.  

This is a function that was trivial and natural for the class designer 
to implement.  It probably IS used internal to the class in order to 
decide whether or not to suspend or resume a thread.  But is of little 
practical value to the end user.  Fageddabouit.

>How can one code if you don't
>reliably know when a Queue is empty or full?
>

Generally, Queues never get "full" and you generally don't care if 
they're empty.  

The import thing about Queues is that the reader thread will 
automatically be suspended when reading from an empty queue and 
furthermore it will automatically wake up when the queue becomes non empty.

All you need from Queues is to create them and to get and put data.

>What this boils down to is: I'm sure I can do the job with the great
>help I've already received, but do not have the confidence to know if
>I'm doing the job the *right* way.
>

If your code does what you want and doesn't take an unreasonable amount 
of time to run on your computer then that's 80% of the "*right*" way. 
 I'll defer to others to argue the remaining 20%.

There really aren't as many alternatives here as you seem to suspect.

You probably should look for a book on concurrent sequential processes. 
 Most of the paradigms and pitfalls are pretty standard and would be 
spelled out in the book.  Unfortunately, I am at a loss to make a 
specific recommendation.  Perhaps somebody else has an idea.

Regards

--jb

-- 
James J. Besemer		503-280-0838 voice
2727 NE Skidmore St.		503-280-0375 fax
Portland, Oregon 97211-6557	mailto:jb at cascade-sys.com
				http://cascade-sys.com	








More information about the Python-list mailing list