ls0f / my-issues

0 stars 0 forks source link

在程序中定义TimeOut #13

Open ls0f opened 8 years ago

ls0f commented 8 years ago

很多时候都会有这样的需求,当一个函数多少时间内没执行完的时候,就pass执行下一个任务,避免盲等,这在boss-worker型的系统中尤为明显。那么我们怎么来设计这个计时器呢?

如果我们自己来实现,最简单的做法是开另外一个线程来计时。当到时间的时候发送一个信号给另外一个线程。实际Linux内核已经实现了这个功能。

使用alarm可以设置一个定时器,在将来某个时间内计时器会超时,产生SIGALRM信号。如果程序没有处理这个信号,默认是终止程序。每个进程只有一个alarm时钟,多次调用会覆盖上一次设置的值,以最新的指为准。alarm(0)则是取消闹钟。

有了alarm,我们便可以很方便的在程序中设置TimeOut。下面是一个Python的简单实现:

class TimeOutError(Exception):
        pass

class TimeOut(object):
    def __init__(self, seconds=1, error_message='TimeOut'):
        self.seconds = seconds
        self.error_message = error_message
    def handle_timeout(self, signum, frame):
        raise TimeOutError(self.error_message)
    def __enter__(self):
        signal.signal(signal.SIGALRM, self.handle_timeout)
        signal.alarm(self.seconds)
    def __exit__(self, type, value, traceback):
        signal.alarm(0)

with TimeOut(2):
    requests.get("http://httpbin.org/delay/3")

requests.get 将会触发自定义的TimtOutError