Python: method call time and terminate it if time is exceeded

I need to dynamically load the code (comes as a source), run it and get the results. The code I download always includes a run method that returns the necessary results. Everything looks ridiculously easy, as usual in Python, as I can do

exec(source) #source includes run() definition
result = run(params)
#do stuff with result

The only problem is that the run () method in dynamically generated code could potentially not complete, so I need to run it only up to x seconds. I could create a new thread for this and specify the time for the .join () method, but then I cannot easily get the result from it (or I can). Performance is also an issue to consider, as it all happens in a long cycle.

Any suggestions on how to proceed?

Edit: to clear things up on a dcrosta request: the downloaded code is not unreliable, but is automatically generated by the machine. The purpose of this is genetic programming.

+3
source share
7 answers

The only “really good” solutions — practically no overhead — will be based on SIGALRM, either directly or through a good layer of abstraction; but, as already noted, Windows does not support this. Threads are not needed, and not because it is difficult to get results (it would be trivial, with a queue!), But because forcing the running thread in a good cross-platform mode is not feasible.

multiprocessing - . , (, -, runaway , , ). , Queue ( ) ( , , ).

, , , ( LAN), , IPC .., , ( ), .

+3

multiprocessing .join() , -, , . - Value (. ), , . terminate() , , .

+2

Stackless Python, . . .

+2

.join(),

, , , . , - , ( ).

SIGALRM , , , . ( , ). :

try:
    # code
finally:
    cleanup1()
    cleanup2()
    cleanup3()

, SIGALRM, 2(), , cleanup3() . Python , .

- .

import threading
from datetime import datetime, timedelta

local = threading.local()
class ExecutionTimeout(Exception): pass

def start(max_duration = timedelta(seconds=1)):
    local.start_time = datetime.now()
    local.max_duration = max_duration

def check():
    if datetime.now() - local.start_time > local.max_duration:
        raise ExecutionTimeout()

def do_work():
    start()
    while True:
        check()
        # do stuff here
    return 10

try:
    print do_work()
except ExecutionTimeout:
    print "Timed out"

(, , "timeout.start()"; "timeout.check()".)

, timeout.check() .

+1

, , . , , run(), run() : , , ..

, , , SO .

0
source

quick google for "python timeout" shows class TimeoutFunction

0
source

Consider using the stopit package, which can be useful; in some cases, you may need a timeout. His document highlights the limitations.

https://pypi.python.org/pypi/stopit

0
source

Source: https://habr.com/ru/post/1718553/


All Articles