Advertisement
Guest User

Untitled

a guest
Oct 10th, 2015
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.61 KB | None | 0 0
  1. #-*- coding: utf-8 -*-
  2.  
  3. import sys
  4. import time
  5. import threading
  6.  
  7.  
  8. class KThread(threading.Thread):
  9. """ A subclass of threading.Thread, with a kill() method.
  10.  
  11. """
  12. def __init__(self, *args, **kwargs):
  13. threading.Thread.__init__(self, *args, **kwargs)
  14. self.killed = False
  15.  
  16. def start(self):
  17. """ Start the thread. """
  18. self.__run_backup = self.run
  19. self.run = self.__run # Force the Thread to install our trace.
  20. threading.Thread.start(self)
  21.  
  22. def __run(self):
  23. """ Hacked run function, which installs the trace. """
  24. sys.settrace(self.globaltrace)
  25. self.__run_backup()
  26. self.run = self.__run_backup
  27.  
  28. def globaltrace(self, frame, why, arg):
  29. if why == 'call':
  30. return self.localtrace
  31. else:
  32. return None
  33.  
  34. def localtrace(self, frame, why, arg):
  35. if self.killed:
  36. if why == 'line':
  37. raise SystemExit()
  38. return self.localtrace
  39.  
  40. def kill(self):
  41. self.killed = True
  42.  
  43.  
  44. class Timeout(Exception):
  45. """ function run timeout """
  46.  
  47.  
  48. def timeout(seconds):
  49. """ 超时装饰器,指定超时时间.
  50.  
  51. 若被装饰的方法在指定的时间内未返回,则抛出 Timeout 异常
  52.  
  53. """
  54. def timeout_decorator(func):
  55. """ 真正的装饰器 """
  56.  
  57. def _new_func(oldfunc, result, oldfunc_args, oldfunc_kwargs):
  58. result.append(oldfunc(*oldfunc_args, **oldfunc_kwargs))
  59.  
  60. def _(*args, **kwargs):
  61. result = []
  62. new_kwargs = { # create new args for _new_func, because we want to get the func return val to result list
  63. 'oldfunc': func,
  64. 'result': result,
  65. 'oldfunc_args': args,
  66. 'oldfunc_kwargs': kwargs
  67. }
  68. thd = KThread(target=_new_func, args=(), kwargs=new_kwargs)
  69. thd.start()
  70. thd.join(seconds)
  71. alive = thd.isAlive()
  72. thd.kill() # kill the child thread
  73. if alive:
  74. raise Timeout(u'function run too long, timeout %d seconds.' % seconds)
  75. else:
  76. return result[0]
  77. _.__name__ = func.__name__
  78. _.__doc__ = func.__doc__
  79. return _
  80. return timeout_decorator
  81.  
  82.  
  83. @timeout(5)
  84. def method_timeout(seconds, text):
  85. print 'start', seconds, text
  86. time.sleep(seconds)
  87. print 'finish', seconds, text
  88. return seconds
  89.  
  90.  
  91. if __name__ == '__main__':
  92. for sec in range(1, 10):
  93. try:
  94. print '*' * 20
  95. print method_timeout(sec, 'test waiting %d seconds' % sec)
  96. except Timeout, e:
  97. print e
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement