Threading for a newbie

Jean-Paul Calderone exarkun at divmod.com
Thu Jan 5 18:46:56 EST 2006


On Thu, 05 Jan 2006 17:15:20 -0500, Koncept <user at unknown.invalid> wrote:
>
>Hi. I am fairly new to Python programming and am having some trouble
>wrapping my head around threading.
>

It's pretty much the standard threading model.

>This is a very basic example of what I am trying to do, and would
>greatly appreciate having this code hacked to pieces so that I can
>learn from you folks with experience.
>
>What I would like to learn from this example is how to use threads to
>call on other classes and append/modify results in a list outside of
>scope (basically keep track of variables throught the total threading
>process and return them somehow afterwards ). I was thinking about
>using some sort of global, but I am not sure what the best approach to
>this is.

Why would anyone want to learn that?  What you want to do is learn how 
to *avoid* doing that :P  Writing threaded programs that do anything 
other than allow individual threads to operate on an isolated chunk of 
input and return an isolated chunk of output is extremely difficult; 
perhaps even impossible.

>
>Thanks kindly for any assistance you may be able to offer.
>
>-- code --
>
>import time, random, threading
>
>order = []
>
>class Foo:
>   def __init__(self, person):
>      print "\nFoo() recieved %s\n" % person
>
>class Bar(threading.Thread, Foo):
>   def __init__(self, name):
>      threading.Thread.__init__(self, name = name)
>      self.curName = name
>   def run(self):
>      global order
>      sleepTime = random.randrange(1,6)
>      print "Starting thread for %s in %d seconds" % \
>         (self.getName(), sleepTime)
>      time.sleep(sleepTime)
>      Foo.__init__(self,self.getName())
>      print "%s's thread has completed" % self.getName()
>      order.append(self.getName())

Note that above you are sharing not only `order' between different 
threads (the append method of which is threadsafe, so this is 
nominally okay) and you are *also* sharing standard out, which is 
not safe to use in the manner you are using it.  The program contains 
a subtle race condition which can cause output to be misformated.
You need to change the print statements to single sys.stdout.write 
calls, or use a lock around any print.

>
>def main():
>   for person in ['Bill','Jane','Steve','Sally','Kim']:
>      thread = Bar(person)
>      thread.start()

  To answer the question you asked, accumulate the threads in a 
list.  After you have started them all, loop over the list calling 
join on each one.  join will block until the thread's function 
returns.

>
>   # How do I print "order" after all the threads are complete?
>   print "\nThreads were processed in the following order:"
>   for i, person in enumerate(order): print "%d. %s" % (i+1,person)
>
>if __name__ == "__main__":
>   main()
>

Jean-Paul



More information about the Python-list mailing list