Open xixiaocheng opened 6 years ago
dear xixiao, timer signals can not be used in Windows at all. You might use this decorator with option use_signals=False, or You might use my fork - there the signals are disabled by default in windows : https://github.com/bitranox/wrapt-timeout-decorator
yours sincerely
Robert
Thanks! I just use your sample code to execute at pycharm.
Error message: pickle.PicklingError: Can't pickle <function mytest at 0x00000000025E9D68>: it's not the same object as main.mytest
Dear Xixiao, try not to call if from main - I will change the sample code accordingly. BTW, happy chinese new year
so smt. like :
import time
from wrapt_timeout_decorator import *
@timeout(5)
def mytest(message):
print(message)
for i in range(1,10):
time.sleep(1)
print('{} seconds have passed'.format(i))
def main():
mytest('starting')
if __name__ == '__main__':
main()
yours sincerely
Robert
I also have a request. add an option message="xxxxxxxxxxxxxxxxxxxx"
If the function timeout. Error message will also show~
You can already customize the exception message : @timeout(... ,exception_message='something') if You need to do that. But to keep the decorator generic, You should catch the Timeout Exception and there print/log whatever You want.
import time
from wrapt_timeout_decorator import *
@timeout(5)
def mytest(message):
print(message)
for i in range(1,10):
time.sleep(1)
print('{} seconds have passed'.format(i))
def main():
try:
mytest('starting')
except TimeoutError as exc:
print('whatever You want')
# take a closer look using
# sys.excinfo() or
# traceback.print_exc()
# reraise if needed:
raise TimeoutError from exc
if __name__ == '__main__':
main()
Thank you! Your help is very useful! By the way, what's the difference between the wrapt-timeout-decorator and timeout-decorator
Dear Xiaxiao, the timeout decorator is using functools for wrapping the function --> see sourcecode:
# pnpnpn timeout decorator:
from functools import wraps
we use wrapt, what is more persistent, especially when You debug in pycharm. Also it provides better support in decorating methods of classes, static methods, etc.:
# wrapt-timeout-decorator
import wrapt
but most important for windows is, that we use "dill + multiprocess" instead of "pickle + multiprocessing" - distinct "multiprocess" != "multiprocessing" !!!
# pnpnpn timeout decorator:
import multiprocessing # implizitely imports pickle
# wrapt-timeout-decorator
# of course You need to install dill and multiprocess via pip first
# see the links further below
import dill # the better sibling of pickle
import multiprocess # the better sibling of multiprocessing, using dill instead pickle
since we dont have signals in Windows, we need to run the decorated function in a seperate process that can be terminated after the timeout occurs (You can not terminate threads). In order to do that, the decorated function have to be "pickled" (serialized).
pickle is somehow limited, dill can serialize more types then pickle. This is important, because if the decorated function or method contains some elements that are not pickable, the decorator will fail with smth, like " ... not pickable " see : https://pypi.python.org/pypi/dill see : https://github.com/uqfoundation/multiprocess see: https://stackoverflow.com/questions/19984152/what-can-multiprocessing-and-dill-do-together
conclusion:
# try to test Your programs with following imports - should pass without problems
# of course You need to install dill and multiprocess via pip first
import dill as pickle
import multiprocess as multiprocessing
yours sincerely
Robert
import time
from timeout_decorator import *
@timeout(5)
def mytest(message):
print(message)
for i in range(1,10):
time.sleep(1)
print('{} seconds have passed'.format(i))
def main():
try:
mytest('starting')
except TimeoutError:
print('whatever You want')
if __name__ == '__main__':
main()
raise error:
File "C:\Install\Anaconda3\lib\site-packages\timeout_decorator\timeout_decorator.py", line 78, in new_function
old = signal.signal(signal.SIGALRM, handler)
AttributeError: module 'signal' has no attribute 'SIGALRM'
You use pnpnpn´s timeout decorator from here - so You need to put use_signals=False on windows, so:
@timeout(5, use_signals=False)
def mytest(message):
...
my fork does that automatically, You can look here :
https://github.com/bitranox/wrapt-timeout-decorator
yours sincerely
Robert
Maybe it's the problem that windows didn't support signal well.
But do you have any solution ?