Skip to content

Instantly share code, notes, and snippets.

@momijiame
Created August 26, 2016 07:27
Show Gist options
  • Save momijiame/2effd18125572a2762e6edade6123b13 to your computer and use it in GitHub Desktop.
Save momijiame/2effd18125572a2762e6edade6123b13 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import functools
import threading
import time
try:
# Python 3
from queue import Queue
except ImportError:
# Python 2
from Queue import Queue
class Timeout(Exception):
pass
def _run(q, f, args, kwargs):
return_value = f(*args, **kwargs)
q.put(return_value)
def _spawn(n, f, args, kwargs):
q = Queue(1)
t = threading.Thread(target=_run, args=(q, f, args, kwargs))
t.start()
t.join(n)
if t.is_alive():
raise Timeout()
return_value = q.get()
return return_value
def timeout(n):
"""このデコレータで装飾された関数は、実行に n 秒以上がかかったとき Timeout 例外を送出する。
装飾された関数の実行はタイムアウトが発生した後もバックグラウンドで継続する。
これは、装飾された関数が別のスレッド上で実行されることに由来している。
Python のスレッドは別のスレッドから停止したり例外を送り込むことができない。
"""
def _timeout(function):
@functools.wraps(function)
def __timeout(*args, **kwargs):
return _spawn(n, function, args, kwargs)
return __timeout
return _timeout
@timeout(2)
def do_something():
time.sleep(4)
print('Complete')
def main():
start = time.time()
try:
do_something()
except Timeout:
pass
end = time.time()
msg = 'Elapsed time: {0}sec'.format(end - start)
print(msg)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment