I am using Python 3.5.2 on windows.
I would like to run a python script but guarantee that it will not take more than N seconds. If it does take more than N seconds, an exception should be raised, and the program should exit. Initially I had thought I could just launch a thread at the beginning that waits for N seconds before throwing an exception, but this only manages to throw an exception to the timer thread, not to the parent thread. For example:
import threading
import time
def may_take_a_long_time(name, wait_time):
print("{} started...".format(name))
time.sleep(wait_time)
print("{} finished!.".format(name))
def kill():
time.sleep(3)
raise TimeoutError("No more time!")
kill_thread = threading.Thread(target=kill)
kill_thread.start()
may_take_a_long_time("A", 2)
may_take_a_long_time("B", 2)
may_take_a_long_time("C", 2)
may_take_a_long_time("D", 2)
This outputs:
A started...
A finished!.
B started...
Exception in thread Thread-1:
Traceback (most recent call last):
File "C:\Program Files\Python35\lib\threading.py", line 914, in _bootstrap_inner
self.run()
File "C:\Program Files\Python35\lib\threading.py", line 862, in run
self._target(*self._args, **self._kwargs)
File "timeout.py", line 11, in kill
raise TimeoutError("No more time!")
TimeoutError: No more time!
B finished!.
C started...
C finished!.
D started...
D finished!.
Is this even remotely possible? I realize I could do something like this:
import threading
import time
def may_take_a_long_time(name, wait_time, thread):
if not thread.is_alive():
return
print("{} started...".format(name))
time.sleep(wait_time)
print("{} finished!.".format(name))
def kill():
time.sleep(3)
raise TimeoutError("No more time!")
kill_thread = threading.Thread(target=kill)
kill_thread.start()
may_take_a_long_time("A", 2, kill_thread)
may_take_a_long_time("B", 2, kill_thread)
may_take_a_long_time("C", 2, kill_thread)
may_take_a_long_time("D", 2, kill_thread)
But this method fails if, for example, may_take_a_long_time("B", 60, kill_thread)
was called.
So I guess my TL;DR question is, what's the best way to put a time limit on the main thread itself?
You can use
_thread.interrupt_main
(this module is calledthread
in Python 2.7):If the parent thread is the root thread, you may want to try
os._exit(0)
.