Threads in Python version 1.5, thread doesn't start until calling process dies

David Bolen db3l at fitlinxx.com
Thu Jul 26 19:41:55 EDT 2001


kentabacchi at excite.com (Ken Tabacchi) writes:

> Something interesting I discovered this morning, my implementation of
> the thread module works as expected when run in Pythonwin (1.5.1), but
> gives the erroneous result (thread doesn't start until process that
> called it has died) when run in the Control Desk environment.

I don't know anything about the environment, but is it just used to
execute an external Python application, or does it have its own
embedded interpreter from which it executes your scripts?

If the latter, and if there are any callbacks into the surrounding
Control Desk environment, then one question would be whether Control
Desk is written to be thread-friendly or not - perhaps it's not
relinquishing the global interpreter lock when working within its own
extensions and thus preventing any other Python threads from running.

> Same interpreter yet different result.  It has been suggested to use
> the threading module for a more 'predictable' execution.  Does anyone
> have any advice about simply starting a new thread, exiting a thread
> and possibly acquiring a lock using the threading module?  Much
> appreciated.

I'm not sure that you're likely to get much different behavior from
threading than from thread, if only because it sounds like your issue
is lower level than that, but here's tiny example of starting up a
thread with the threading module.

I find it most convenient to subclass the Thread object rather than
using the generic class with a callable target, although either
approach will work.  You can create as many instances (threads) of
this object to compete.  I've used a simple mutex lock to match with
your thread usage, but the threading module has a variety of
synchronization primitives for other purposes as well.

Note that threading is one of a few modules built to be friendly for
"from xxx import *", and since it implements some fundamental
constructs that get used frequently in multi-threaded code, it's one
of the very few cases where I do use that form of import.

This sample defines a thread that loops, pausing for random intervals
from 0-1s, then grabs a lock, prints a message, and releases the lock.
Several such thread object instances are created to compete for the
lock.  An event object is used to signal from the main thread that the
threads should terminate.

    import time
    import random
    from threading import *

    # Any thread is created as an instance of the Thread class
    class MyThread(Thread):

	def __init__(self, threadname, lock, event):
	    # You must call Thread.__init__ but can add other parameters
	    # to this thread method - such as lock and event here.
	    Thread.__init__(self,name=threadname)
	    self.lock  = lock
	    self.event = event

	def run(self):
	    # This method is what runs when start() is called
	    while 1:

		# Exit out if event triggers us to do so
		if self.event.isSet():
		    print '%s terminating' % self.getName()
		    return

		# Otherwise wait until we can get a lock
		self.lock.acquire()
		print '%s running' % self.getName()
		self.lock.release()
		time.sleep(random.random())


    if __name__ == "__main__":

	# Create the lock and event objects used for synchronization.
	# From the recent case sensitivity discussion, this exhibits
	# bad form as judged by about half of those reading this. :-)
	lock = Lock()
	event = Event()

	# Create 5 threads to compete
	threads = []
	for i in range(5):
	    threads.append(MyThread('Thread %d' % i+1,lock,event))

	# Start them off
	for curthread in threads:
	    curthread.start()

	# Do something in main thread if you like
	time.sleep(10)

	# Signal termination by activating the event
	event.set()

	# And then wait for the threads to terminate
	for curthread in threads:
	    curthread.join()

--
-- David
-- 
/-----------------------------------------------------------------------\
 \               David Bolen            \   E-mail: db3l at fitlinxx.com  /
  |             FitLinxx, Inc.            \  Phone: (203) 708-5192    |
 /  860 Canal Street, Stamford, CT  06902   \  Fax: (203) 316-5150     \
\-----------------------------------------------------------------------/



More information about the Python-list mailing list