Threading problem (or Queue)

Lev Elbert
2004-12-29
2013-03-15
  • Lev Elbert

    Lev Elbert - 2004-12-29

    """
    Sorry for the long post, but it includes the fix too!

    Here is a little script. 2 classes are created: StopItem and timer(threading.Thread)

    timer waits on the Queue and at given intervals executes a function. One even may be put into the Queue - StopEvent. In this case timer thread terminates.
    """
    import threading
    import time
    import Queue
    import sys
    """ Classes - timer periodically calls timerfunction (has to be overwritten)
                  threadpool creates poll of threads waiting on queue
    """
       
    class StopItem:
        def __init__(self):
            pass
           
    class timer(threading.Thread):
        """
        Periodically calls a function in the derived class
        """
        def __init__(self, interval = 1, timestorepeat=None, name=None, args=(), kwargs={}):
            """
            Constructor
           
            interval - how often to call the function, default 1 second
            timestorepeat - how many times (Nome - infinite)
            name - thread name
            """
            threading.Thread.__init__(self, name = name, args = args, kwargs = kwargs)
            self.timestorepeat = timestorepeat
            self.interval = interval
            self.lapnumber = 0
            self.queue = Queue.Queue()
           
        def run(self):
            """
            Overites Thead.run method. Runs until stop is called or
            function is executed self.timestorepeat times
            """
            while True:
                if self.timestorepeat is not None and self.lapnumber > self.timestorepeat:
                    break
                try:               
                    self.item = self.queue.get(True, self.interval)
                    if isinstance(self.item, StopItem):
                        break
                except Queue.Empty:
                    try:
                        self.timerfunction()
                    except:
                        print sys.exc_info()
                    self.lapnumber += 1

        def timerfunction(self): # has to be overwritten
            raise NotImplementedError("Derived class has to implement timerfunction(self)")
       
        def stop(self, timeout = None):
            """ Stops timer
            """
            self.queue.put(StopItem())
            toWait = timeout
            if timeout is None or timeout > 0:
                toWait = None
                self.join(toWait)
            return not self.isAlive()

    if __name__ == '__main__':
        import msvcrt

        class MyTimerThread(timer):
            """
            Example of derived class.
            """
            def __init__(self, interval, timestorepeat=None, name = None):
                timer.__init__(self, interval, timestorepeat, name = name)
                self.counter = 0
           
            def timerfunction(self):
                self.counter += 1
                print self.counter, self.getName()
         
        t = MyTimerThread(1, name = 'MyTimerThread')
        t.start()
        try:
            while not msvcrt.kbhit():
                time.sleep(0.1)
            while msvcrt.kbhit():
                msvcrt.getch()
        except:
            pass
        print t.stop()
       
    """
    here is the output when I run it in the debug mode.
    Exception in thread MyTimerThread:
    Traceback (most recent call last):
      File "G:\Python23\lib\threading.py", line 436, in __bootstrap
        self.run()
      File "G:\eclipse\workspace\ct_lib\example.py", line 31, in run
        def run(self):
      File "g:\eclipse\plugins\org.python.pydev.debug_0.8.0\pysrc\pydevd.py", line 568, in trace_dispatch
        self.processInternalCommands()
      File "g:\eclipse\plugins\org.python.pydev.debug_0.8.0\pysrc\pydevd.py", line 434, in processInternalCommands
        queue = self.getInternalQueue(id(threading.currentThread()))
      File "g:\eclipse\plugins\org.python.pydev.debug_0.8.0\pysrc\pydevd.py", line 411, in getInternalQueue
        self.cmdQueue[thread_id] = Queue()
    TypeError: 'module' object is not callable

    I beleive that the problem is in me importing the Queue module (as g:\eclipse\plugins\org.python.pydev.debug_0.8.0\pysrc\pydevd.py,
    does.

    I had to replace
    from Queue import *
    with
    import Queue
    and make correspondent chamges to make the pydevd.py working
    """

     
    • Anonymous - 2004-12-30

      Cool. If you know a workaround where I can patch pydevd.py so that this is not a problem, I'd be happy to take it.

      Aleks

       
      • Lev Elbert

        Lev Elbert - 2004-12-30

        Workaround is in the first message:

        I beleive that the problem is in me importing the Queue module (as g:\eclipse\plugins\org.python.pydev.debug_0.8.0\pysrc\pydevd.py, 
        does. 

        I had to replace 
        from Queue import * 
        with
        import Queue
        and make correspondent changes to make the pydevd.py working
        =============================

        It works, but I do not know, why it did not before the changes. (:

         
        • Anonymous - 2004-12-30

          Thanks, fixed & checked in.

           
    • Lev Elbert

      Lev Elbert - 2004-12-30

      Sorry!

      It was good, but not good enough. I found "the offender". I was in one module importing Queue, the first change:

      from Queue import * 
      REPLACE WITH
      import Queue 
      fixed thise case, but...

      In another module I had:

      form Queue import Queue
      thise confuses pydevd.py and it tells that "class Queue doesn;t have attribute Empty".

      Final solution

      from Queue import * 
      REPLACE WITH
      import Queue as QueueModule

      Works in all the cases.

      BUT I WHAT IF SOMEBODY HAS QueueModule class?

      Somehow pydevd.py "inherits" the module under debuging environment.

       
      • Anonymous - 2004-12-30

        k, the final answer was
        import Queue as PydevQueue

        Fixed and checked in.

        Aleks