Help: puzzled about threads

Gonçalo Rodrigues op73418 at mail.telepac.pt
Sat Feb 15 14:50:54 EST 2003


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




More information about the Python-list mailing list