Help: puzzled about threads

Anton Muhin antonmuhin at sendmail.ru
Sat Feb 15 21:35:57 CET 2003


Gonçalo Rodrigues wrote:
> Hi,
> 
> A few months ago, I started learning about threads. So I started looking
> at the high level threading module and thought about reimplementing it
> to see if I could understand what was going on.
> 
> I did - and needless to say, I found no improvements to make. Anyway, a
> couple days ago I started testing the sucker and I stumbled upon a very
> puzzling thing.
> 
> I post here a test script, with a trimmed down version of the code:
> 
> #Import modules.
> import thread
> 
> 
> #Global thread functions.
> def CurrentThreadId():
>     """Returns the current thread id."""
>     return thread.get_ident()
> 
> 
> #Module specific exceptions.
> class ThreadError(thread.error):
>     """The ThreadError exception class."""
>     pass
> 
> 
> #The Thread class.
> class Thread(object):
>     """The Thread class."""
> 
>     __initialized = 0
> 
>     def __init__(self):
>         """The initializer."""
>         super(Thread, self).__init__()
>         self.__id = None
>         #The stop flag.
>         self.__stop = 0
>         #Signal thread is initialized.
>         self.__initialized = 1
> 
>     #Properties.
>     def __get_id(self):
>         return self.__id
> 
>     id = property(__get_id,
>                   "Thread id. None means the thread has not started.")
> 
>     #Methods.
>     def isAlive(self):
>         """Return 1 if the thread is alive, 0 otherwise."""
>         #Guarantee thread is initialized.
>         if not self.__initialized:
>             raise ThreadError("Thread not initialized.")
>         return (self.__id is not None) and (not self.__stop)
> 
>     def __repr__(self):
>         #Guarantee thread is fully initialized.
>         if not self.__initialized:
>             raise ThreadError("Thread not initialized.")
>         status = "Initialized"
>         if self.__id is not None:
>             status = "Running"
>         if self.__stop:
>             status = "Stopped"
>         return "<%s(%s, %s)>" % (self.__class__.__name__,
>                                  self.__id,
>                                  status)
> 
>     def __bootstrap(self):
>         #If thread was stopped reset the flag.
>         if self.__stop:
>             self.__stop = 0
>         #Set id of the thread.
>         self.__id = CurrentThreadId()
>         try:
>             self.run()
>         finally:
>             #Signal the thread has stopped running.
>             self.__stop = 1
> 
>     def start(self):
>         """Start the thread, returning the thread id."""
>         #Guarantee our object is fully initialized.
>         if not self.__initialized:
>             raise ThreadError("Thread not initialized.")
>         #If stopped we're OK => we can restart the thread.
>         if self.isAlive():
>             raise ThreadError("Thread is running.")
>         #This guarantees that self.__bootstrap runs in the thread we
> spawned.
>         id = thread.start_new_thread(self.__bootstrap, ())
>         return id
> 
>     def run(self):
>         """The run method."""
>         raise NotImplementedError("You must override the run method.")
> 
> 
> if __name__ == '__main__':
>    #A mock thread that dies immediately.
>     class MockThread(Thread):
>         def run(self):
>             return
> 
>     mockthread = MockThread()
>     id = mockthread.start()
>     #Sleep wait until thread dies.
>     while mockthread.isAlive():
>         time.sleep(0.001)
>     if not mockthread.id == id:
>         print "Error: thread id mismatch. thread id is %s." %
> mockthread.id
>     print repr(mockthread)
> 
> When I run it, I get the following output:
> 
> Error: thread id mismatch. thread id is None.
> <MockThread(None, Initialized)>
> 
> Of course I was expecting as output:
> 
> <MockThread(some-integer-here, Stopped)>
> 
> The output seems to say that in the self.__bootstrap call, neither
> self.__id neither self.__stop are being set. Can anyone help me out
> here? What the hell am I doing wrong?
> 
> Note: The script was run from PythonWin, Windows2000 platform.
> 
> With my best regards,
> G. Rodrigues

Your thread didn't manage to start:
if you add the following lines, "sleeping..." won't print
     while mockthread.isAlive():
         print "Sleeping..."
         time.sleep(0.001)

But if you add
	time.sleep(0.01)
before the loop above, everything will be OK.

HTH,
Anton.





More information about the Python-list mailing list