tags:

views:

473

answers:

3

Is there any standard python module for creating multiple periodic timers. I want to design a system which supports creating multiple periodic timers of different periodicity running in just one thread. The system should be able to cancel a specific timer at any point of time.

Thanks in advance for any input!

+1  A: 

If you have to stick with 1 thread - maintain a list of tasks, along with the frequency they should execute and what function should be called:

import time

def example1():
    print 'Example'

class Task(object):
    def __init__(self, func, delay, args=()):
        self.args = args
        self.function = func
        self.delay = delay
        self.next_run = time.time() + self.delay

    def shouldRun(self):
        return time.time() >= self.next_run

    def run(self):
        self.function(*(self.args))
        self.next_run += self.delay
        # self.next_run = time.time() + self.delay

tasks = [Task(example1, 1)] # Run example1 every second
while True:
    for t in tasks:
        if t.shouldRun():
            t.run()
        time.sleep(0.01)

Or you may want to have a look at stackless - which is ideally suited to what you want to do, and makes it possible to do much finer grained task-switching than the above scheduler.

gridzbi
Looks like NIH, when one can use the sched module pointed at by Alex Martelli in his answer.
ddaa
+2  A: 

Check out the sched module in Python's standard library -- per se, it doesn't directly support periodic timers, only one-off "events", but the standard trick to turn a one-off event into a periodic timer applies (the callable handling the one-off event just reschedules itself for the next repetition, before moving on to doing real work).

It may be handy to define a "scheduled periodic timer" class to encapsulate the key ideas:

class spt(object):

  def __init__(self, scheduler, period):
    self._sched = scheduler
    self._period = period
    self._event = None

  def start(self):
    self._event = self._sched.enter(0, 0, self._action, ())

  def _action(self):
    self._event - self._sched.enter(self._period, 0, self._action, ())
    self.act()

  def act(self):
    print "hi there"

  def cancel(self):
    self._sched.cancel(self._event)

To associate a meaningful action to a scheduled periodic timer, subclass spt and override the act method (a Template Method design pattern). You can of course choose more flexible architectures, such as having __init__ take a callable and arguments as well as a scheduler (an instance of self.scheduler) and a period (as a float in seconds, if you instantiate the scheduler in the standard way with time.time and time.sleep); optionally you might also want to set a priority there (maybe with a default value of 0) rather than using the constant 0 priority I'm using above.

Alex Martelli
A: 

Hi guys,

can somebody tell me how to use this class timers from python in my code more than one time.

import MOD

class timer:

def __init__(self, seconds):
self.start(seconds)

def start(self, seconds):
self.startTime = MOD.secCounter()
self.expirationTime = self.startTime + seconds
if seconds != 0:
  self.running = 1
  self.expired = 0
else:
  self.running = 0
  self.expired = 0

def stop(self):
self.running = 0
self.expired = 0

def isexpired(self):
if self.running == 1:
  timeNow = MOD.secCounter()
  if timeNow > self.expirationTime:
    self.running = 0
    self.expired = 1
  else:
    self.expired = 0
return self.expired

def isrunning(self):
if self.running == 1:
  timeNow = MOD.secCounter()
  if timeNow > self.expirationTime:
    self.running = 0
    self.expired = 1
  else:
    self.expired = 0
return self.running

def change(self, seconds):
self.expirationTime = self.startTime + seconds

def count(self):
if self.running == 1:
  timeNow = MOD.secCounter()
  return (timeNow - self.startTime)
else:
  return -1

they write this comment:

The following is a simple example about how to use this class:
import timers
timerA = timers.timer(0)
timerA.start(15)
while 1:
  if timerA.isexpired():
    print 'timerA expired'
    break

but I don't know how to use it more than one time in my code, because I need to use more than one timer in my code,

should I write

timerB = timers.timer(1)
timerB.start(1800)
while 1:
  if timerB.isexpired():
    print 'timerA expired'
    break

any help, please

mahdi86
This is a question, not an answer. Please make this its own question.
Mike D.