0

I wonder is there a way to execute a function for a fixed duration in Python?

I guess it could be implemented using a decorator, for example:

def terminate_if_runs_too_long(func):
    def new_func(*args, **kwargs):
        with <lock which is valid for fixed duration>:
            return func(*args, **kwargs)
    return new_func

@terminate_if_runs_too_long
def infinite_loop():
    '''Imported function, which cannot be modified'''
    while True:
        pass

However, I am not sure how to implement the resource/lock which would be available for a fixed duration and would raise an exception once the usage duration is exceeded.

I am looking for a solution, which would work using a single thread.

niekas
  • 8,187
  • 7
  • 40
  • 58

1 Answers1

1

There's no safe way to do this in general if you don't have control over the function. One reason is that the function could be in the middle of modifying something and killing it could leave that something in a bad state. See this question.

Brian McCutchon
  • 8,354
  • 3
  • 33
  • 45
  • 1
    Its fine for me if a state gets corrupted. Is there a way to do it without using `threading` package? – niekas Oct 23 '20 at 05:33
  • You could use `multiprocessing`, as [this answer](https://stackoverflow.com/a/7752174/2093695) suggests, but maybe that's not what you meant. You could do something hacky like monkey-patching some frequently-called dependency of the function to add a check that throws an exception if the time is up, but that's brittle. – Brian McCutchon Oct 23 '20 at 06:13
  • I wonder would it be possible to solve it using Coroutines? An asynchronous task, which raises an exception after duration could be started before executing long running function. And this asynchronous task could be aborted after execution of the long running function. – niekas Oct 23 '20 at 06:57
  • No, that wouldn't work. The exception would happen outside the function you're trying to stop, so it wouldn't stop it. Besides, if the function and coroutine really ran simultaneously, you would be using threads or multiprocessing anyway. – Brian McCutchon Oct 23 '20 at 15:14