Thread Question

Laurent POINTAL pointal at lure.u-psud.fr
Fri May 19 16:29:42 CEST 2000


On Thu, 18 May 2000 04:07:37 GMT, "Karl Lewin" <lewinke at home.com>
wrote:

>: Is there a way to "kill" a thread that is currently asleep.
>: 
>: Example:
>: 
>: thread t1 is currently executing "time.sleep(60)", is it possible to
>: kill/delete/destroy the thread object before it finishes sleeping?
>: 
>: If this isn't clear, I can post a better example tomorrow.

Here is a SoftTimer class I just wrote to be able to interrupt a
sleeping thread. It is based on the lock waiting for an event with a
timeout. Example of use:
------------------------------------------------------------------
from softtimermod import SoftTimer
a=SoftTimer()
a.start(60)

# Then you have an a timer which will stop in 60 seconds, and
# when you wants you do:
a.wait()

# Note that you can wait with a timeout.


# In another thread, you can do:
a.interrupt()
# Then all threads waiting on a will get out with a 
# TimerInterruptError exception. Or you can call:
a.stop()
# And all  threads waiting on a will get out normally.

------------------------------------------------------------------
Its recent code, normally tested but there may remain bugs...

A+

Laurent.


------------------------------------------------------------------
#!/bin/env python
"""Software timer management - generic tools.

File  : softtimermod.py
Author: Laurent POINTAL
Date  : 18/05/2000
Modif :
----- DESCRIPTIONS
-----------------------------------------------------------------
A software timer, which can be interrupt before the end.
----- REVISIONS
--------------------------------------------------------------------
"""

# Import modules and symbols, avoid namespace pollution in case of
"import *" of
# this module by redefining imports with _.
import time
_time = time
del time
  
import sys
_sys = sys
del sys

import threading
_threading = threading
del threading

# ----- Constants.

# ----- Globals.
_debug = 0


#================================================================================
# class: TimerInterruptError
class TimerInterruptError (RuntimeError) :
    """Used as exception when a timer end is interrupted."""
    def __init__ (self, reason) :
        RuntimeError.__init__ (self, "Timer has been interrupted.")

#================================================================================
# class: TimerTimeoutError
class TimerTimeoutError(RuntimeError) :
    """Used as exception when a timer wait fail into timeout."""
    def __init__ (self, reason) :
        RuntimeError.__init__ (self, "Timer waiting has timed-out.")
        
#================================================================================
# class: TimerRunningError
class TimerRunningError(RuntimeError) :
    """Used as exception when a timer is already running."""
    def __init__ (self) :
        RuntimeError.__init__ (self, "Timer is already running.")

#================================================================================
# class: SoftTimer
class SoftTimer :
    """Software time measurement.

    Not the best solution, but can be necessary.
    And it is interruptible (in case an external situation make
waiting the end
    of the timer a bad idea) [note that interrupt throw an error for
waiting
    clients, but stop does a normal stop of the timer].
    """
    def __init__ (self) :
        """Construct the software timer."""
        self.__start = 0
        self.__delay = 0
        self.__running = 0
        self.__event = _threading.Event()
        self.__interrupted = 0

    def __halt(self,interrupt) :
        """PRIVATE: Halt the timer.

        Interrupt indicate how the timer is stopped.
        """
        self.__interrupted = interrupt
        self.__running = 0
        self.__event.set()
        
    def interrupt(self) :
        """Stop the current timing on this timer.

        All waiting threads exit with a TimerInterruptError exception.
        """
        if _debug : print "Soft timer interrupted at",_time.time()
        self.__halt(1)
        
    def is_running(self) :
        """Test if the timer is currently running."""
        return self.remain() != 0

    def remaining(self) :
        """Return remaining time on this timer.

        If the timer is not running (no started or finished) then the
        remaining time is 0.
        If the timer is infinite, then the remaining time is -1.
        """
        if not self.__running : return 0

        if self.__delay < 0 : return -1

        # Special cases processed, now calculate true remaining, and
        # if we detect that end of timing is gone, signal it.
        remain = self.__start + self.__delay - _time.time()
        if remain <= 0 :
            self.__halt(0)
            return 0
        else :
            return remain

    def start(self,delay) :
        """Start to count time on the software timer.

        If the delay is negative, then the timer count is infinite
        (ie. the timer must be broken with interrupt or stop).
        """
        if self.__running :
            _sys.stderr.write("Trying to start an already running
timer.")
            raise TimerRunningError

        self.__start = _time.time()
        self.__event.clear()
        self.__delay = delay
        self.__running = 1
        self.__interrupted = 0
        if _debug : print "Soft timer started at",self.__start

    def stop(self) :
        """Stop the timer (normally, like if it was an event).

        To interrupt abnormally the timer, use the interrupt method.
        """
        if _debug : print "Soft timer stopped at",_time.time()
        self.__halt(0)

    def wait(self,timeout=None) :
        """Wait for the end of the timer.
        """
        if self.__interrupted :
            _sys.stderr.write("Timer has been interrupted.")
            raise TimerInterruptError
            
        if not self.__running : return
        
        remain = self.remaining()

        # Dont wait more than the timer remaining time.
        if remain > 0 and (timeout == None or timeout > remain) :
            timeout = remain
            
        if remain != 0 :
            # Wait on the signal.
            if _debug : print "Soft timer waiting for",timeout
            self.__event.wait(timeout)
            if _debug : print "Soft timer exit waiting
at",_time.time()
            if self.__interrupted :
                _sys.stderr.write("Waiting timer has been
interrupted.")
                raise TimerInterruptError
            if self.remaining() > 0 :
                _sys.stderr.write("Waiting timer failed in timeout.")
                raise TimerTimeoutError

------------------------------------------------------------------


---
Laurent POINTAL - CNRS/LURE - Service Informatique Experiences
Tel/fax: 01 64 46 82 80 / 01 64 46 41 48
email  : pointal at lure.u-psud.fr  ou  lpointal at planete.net 



More information about the Python-list mailing list