From 44f8696171f8d9e29c82e250ed90351dfb207da2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20v=2E=20L=C3=B6wis?= Date: Wed, 5 Sep 2001 13:44:54 +0000 Subject: Patch #428326: New class threading.Timer. --- Doc/lib/libthreading.tex | 36 ++++++++++++++++++++++++++++++++++++ Lib/threading.py | 31 ++++++++++++++++++++++++++++++- Misc/NEWS | 3 +++ 3 files changed, 69 insertions(+), 1 deletion(-) diff --git a/Doc/lib/libthreading.tex b/Doc/lib/libthreading.tex index 27503bd..cd77246 100644 --- a/Doc/lib/libthreading.tex +++ b/Doc/lib/libthreading.tex @@ -82,6 +82,10 @@ semaphore is released too many times it's a sign of a bug. If not given, A class that represents a thread of control. This class can be safely subclassed in a limited fashion. \end{classdesc*} +\begin{classdesc*}{Timer}{} +A thread that executes a function after a specified interval has passed. +\end{classdesc*} + Detailed interfaces for the objects are documented below. The design of this module is loosely based on Java's threading model. @@ -595,3 +599,35 @@ The initial value is inherited from the creating thread. The entire Python program exits when no active non-daemon threads are left. \end{methoddesc} + + +\subsection{Timer Objects \label{timer-objects}} + +This class represents an action that should be run only after a certain amount +of time has passed --- a timer. \class{Timer} is a subclass of \class{Thread} and +as such also functions as an example of creating custom threads. + +Timers are started, as with threads, by calling their \method{start()} method. The +timer can be stopped (before its action has begun) by calling the +\method{cancel()} method. The interval the timer will wait before executing +its action may not be exactly the same as the interval specified by the +user. + +For example: +\begin{verbatim} +def hello(): + print "hello, world" + +t = Timer(30.0, hello) +t.start() # after 30 seconds, "hello, world" will be printed +\end{verbatim} + +\begin{classdesc}{Timer}{interval, function, args=[], kwargs=\{\}} +Create a timer that will run \var{function} with arguments \var{args} and +keyword arguments \var{kwargs}, after \var{interval} seconds have passed. +\end{classdesc} + +\begin{methoddesc}{cancel}{} +Stop the timer, and cancel the execution of the timer's action. This will only +work if the timer is still in its waiting stage. +\end{methoddesc} diff --git a/Lib/threading.py b/Lib/threading.py index 268c09c..4906674 100644 --- a/Lib/threading.py +++ b/Lib/threading.py @@ -331,7 +331,6 @@ class _Event(_Verbose): self.__cond.wait(timeout) self.__cond.release() - # Helper to generate new thread names _counter = 0 def _newname(template="Thread-%d"): @@ -483,6 +482,36 @@ class Thread(_Verbose): assert not self.__started, "cannot set daemon status of active thread" self.__daemonic = daemonic +# The timer class was contributed by Itamar Shtull-Trauring + +def Timer(*args, **kwargs): + return _Timer(*args, **kwargs) + +class _Timer(Thread): + """Call a function after a specified number of seconds: + + t = Timer(30.0, f, args=[], kwargs={}) + t.start() + t.cancel() # stop the timer's action if it's still waiting + """ + + def __init__(self, interval, function, args=[], kwargs={}): + Thread.__init__(self) + self.interval = interval + self.function = function + self.args = args + self.kwargs = kwargs + self.finished = Event() + + def cancel(self): + """Stop the timer if it hasn't finished yet""" + self.finished.set() + + def run(self): + self.finished.wait(self.interval) + if not self.finished.isSet(): + self.function(*self.args, **self.kwargs) + self.finished.set() # Special thread class to represent the main thread # This is garbage collected through an exit handler diff --git a/Misc/NEWS b/Misc/NEWS index 5e763c0..a4d7395 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -81,6 +81,9 @@ Core Library +- Asynchronous timeout actions are available through the new class + threading.Timer. + - math.log and math.log10 now return sensible results for even huge long arguments. For example, math.log10(10 ** 10000) ~= 10000.0. -- cgit v0.12