如何在程序中实现多个信号?

时间:2014-05-07 08:45:39

标签: python timer alarms

我开始学习Python(新手),所以不太了解不同的模块等。

我想要模拟的场景:

我有一个程序prg1.py我希望在一些用户定义的时间内运行t秒。在此时间(t秒)之后,程序应退出。为此,我使用signal.signal()来创建警报。以下是工作代码:

    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)

程序运行10秒钟,然后按预期退出 注意:下面的while循环仅用于测试,它将被我的工作代码替换。

现在我想实现多个信号,以不同的时间间隔完成不同的任务。

e.g。在EVERY5秒:执行特定功能fun1()
10秒:执行特定功能fun2(),等等on ...(我想在程序中执行的任务)

我尝试添加另一个警报,如下所示,但不起作用:

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)

这不起作用!简单退出没有任何错误或退出消息:(

如何实施此功能?

注意:Use of Threads is restricted.

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

1 个答案:

答案 0 :(得分:2)

您应该看看sched模块是否可以满足您的要求;另外,为什么不允许多线程?

通过以预定事件期间的最大公约数的时间间隔发出警报,可以使用单个警报计划多个任务。下面是一个例子,但它不是很强大,例如,如果任何任务需要很长时间,那么时间将是不准确的。这是可以修复的(用time.time()跟踪时间,并相应地安排下一个警报),但是其他问题仍然存在(如果一个任务运行得太久以至于下一个任务开始得晚,会发生什么?)。我的看法是,调度程序是一个有许多棘手问题的问题,如果可能的话,你应该使用现有的解决方案,而不是自己编写。

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...'

在我的(python2)系统上,这给出了:

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...