How to implement multiple signals in a program?
Question: I am starting to learn Python (newbie), so not much idea about the different
modules etc.

Scenario that I want to simulate:

I have a program `prg1.py` that I want to run for some user defined time say
`t` seconds. After this time (`t` seconds), the program should exit. For this
I am using `signal.signal()` to create alarm. Below is the working code:

    
    
        import signal
        import time
        import sys
    
        def receive_alarm(signum, stack):
            sys.exit('Exiting!')
    
        signal.signal(signal.SIGALRM, receive_alarm)
        signal.alarm(10)
    
        while 1:
        print 'Working...'
        time.sleep(1)
    

The program runs for 10 seconds and then exits as expected.  
Note: The while loop below is just for testing, it would be replaced by my
working code.

Now I want to implement multiple signals to do different tasks at different
intervals of time.

e.g. In `EVERY`:  
`5` seconds: execute a specific function `fun1()`  
`10` seconds: execute a specific function `fun2()`, and so on... (tasks I want
to perform in the program)

I tried adding another alarm as shown below, but didn't work:

    
    
    import signal
    import time
    import sys
    
    def receive_alarm(signum, stack):
        sys.exit('Exiting!')
    
    def receive_alarm_two(signup, stack):
        print 'Call to other functions!'
    
    signal.signal(signal.SIGALRM, receive_alarm)
    signal.alarm(10)
    
    # Second Alarm
    signal.signal(signal.SIGALRM, receive_alarm_two)
    signal.alarm(2)
    
    while 1:
    print 'Working...'
    time.sleep(1)
    

This doesn't work! Simple exits without any error or exit message :(

How can this functionality be implemented?

NOTE: `Use of Threads is restricted.`  

NOTE: `As I want the program to keep listening to different signals, it can't
sleep i.e. cannot use time.sleep().`


Answer: You should see if your requirements can be met by the `sched` module; also,
why is multithreading not allowed?

It's possible to schedule multiple tasks with a single alarm by having the
alarm occur at time intervals of the greatest common divisor of the period of
your scheduled events. An example is below, but it's not very robust, e.g., if
any task takes very long, the timing will be inaccurate. This is fixable (keep
track of time with `time.time()`, and schedule the next alarm accordingly),
though other problems remain (what happens if one task runs so long that the
next task starts late?). My perception is that schedulers are a problem with
many tricky corner cases, and that if possible you should use an existing
solution, rather than writing your own.

    
    
    import signal
    import time
    
    class Scheduler(object):
        """Trivial scheduler object.
    
        Rather use sched.scheduler"""
    
        def __init__(self):
            self._tasks= [(1,self._heartbeat)]
            self._tick= 0
            self.stopped=False
    
        def addtask(self,period,task):
            """Add a task to be executed every PERIOD seconds
    
            addtask(period,task)
    
            period: seconds
            task: callable taking 'tick' argument
            """
            self._tasks.append( (period,task) )
    
        def _heartbeat(self,tick):
            print 'heartbeat: %d' % tick
    
        def _execute(self,signum,stack):
            if self.stopped:
                return
    
            self._tick += 1
            for period, task in self._tasks:
                if 0==self._tick % period:
                    task(self._tick)
            signal.alarm(1)
    
        def start(self):
            signal.signal(signal.SIGALRM, self._execute)
            signal.alarm(1)
    
        def stop(self):
            self.stopped=True
    
    class Stopper(object):
        """Callable to stop a scheduler"""
        def __init__(self, scheduler):
            self._scheduler=scheduler
    
        def __call__(self,tick):
            print 'stopping at tick',tick
            self._scheduler.stop()
    
    def task3s(tick):
        print '3s task at tick',tick
    
    def task7s(tick):
        print '7s task at tick',tick
    
    s= Scheduler()
    s.addtask(10,Stopper(s))
    s.start()
    
    s.addtask(3,task3s)
    s.addtask(7,task7s)
    
    while not s.stopped:
        time.sleep(0.5)
        print 'mainloop...'
    

On my (python2) system this gives:

    
    
    mainloop...
    heartbeat: 1
    mainloop...
    mainloop...
    heartbeat: 2
    mainloop...
    mainloop...
    heartbeat: 3
    3s task at tick 3
    mainloop...
    mainloop...
    heartbeat: 4
    mainloop...
    mainloop...
    heartbeat: 5
    mainloop...
    mainloop...
    heartbeat: 6
    3s task at tick 6
    mainloop...
    mainloop...
    heartbeat: 7
    7s task at tick 7
    mainloop...
    mainloop...
    heartbeat: 8
    mainloop...
    mainloop...
    heartbeat: 9
    3s task at tick 9
    mainloop...
    mainloop...
    heartbeat: 10
    stopping at tick 10
    mainloop...
    

