Jake
Jake

Reputation: 16887

Use timeout to return if function has not finished

I have the following scenario:

res = []

def longfunc(arg):
    # function runs arg number of steps
    # each step can take 500 ms to 2 seconds to complete
    # longfunc keeps adding result of each step into the array res 

def getResult(arg,timeout):
    # should call longfunc()
    # if longfunc() has not provided result by timeout milliseconds then return None
    # if there is partial result in res by timeout milliseconds then return res
    # if longfunc() ends before timeout milliseconds then return complete result of longfunc i.e. res array

result = getResult(2, 500)

I am thinking of using multiprocessing.Process() to put longfunc() in a separate process, then start another thread to sleep for timeout milliseconds. I can't figure out how to get result from both of them in the main thread and decide which one came first. Any suggestions on this approach or other approaches are appreciated.

Upvotes: 1

Views: 746

Answers (2)

Ujjwal Dash
Ujjwal Dash

Reputation: 823

If you are applying multiprocessing then you have to simply apply p.join(timeout=5) where p in a process Here is a simple example

import time
from itertools import count
from multiprocessing import Process
def inc_forever():
    print('Starting function inc_forever()...')
    while True:
        time.sleep(1)
        print(next(counter))
def return_zero():
    print('Starting function return_zero()...')
    return 0
if __name__ == '__main__':
    # counter is an infinite iterator
    counter = count(0)
    p1 = Process(target=inc_forever, name='Process_inc_forever')
    p2 = Process(target=return_zero, name='Process_return_zero')
    p1.start()
    p2.start()
    p1.join(timeout=5)
    p2.join(timeout=5)
    p1.terminate()
    p2.terminate()
if p1.exitcode is None:
       print(f'Oops, {p1} timeouts!')
if p2.exitcode == 0:
        print(f'{p2} is luck and finishes in 5 seconds!')

I think it may help you

Upvotes: 1

Danilo Toro
Danilo Toro

Reputation: 597

You can use time.perf_counterand your code will see:

import time 
ProcessTime = time.perf_counter  #this returns nearly 0 when first call it if python version <= 3.6
ProcessTime() 
def longfunc(arg, timeout):
    start = ProcessTime()
    while True
        # Do anything
        delta = start + timeout - ProcessTime()
        if delta > 0:
            sleep(1)
        else:
            return #Error or False 
    

you can change While for a for loop an for each task, check timeout

Upvotes: 1

Related Questions