learner
learner

Reputation: 2742

How to terminate an ongoing processing abruptly

I am trying to call a python function using subprocess call. I have seen many examples of subprocess but didn't see any that call another python function. I am not sure if it can be done or not.

My function fakeFxn do some processing that may take time as little as few seconds or as long as couple of hours. I want to skip those that takes more than a particular time, say 1 hour. This function is also returning me some value that I need to collect.

def fakeFxn(val):
    if (val== "terminate"):
        for i in range(10):
            z = "t"
        return(z)
    else:
        for i in range(100000000): #Instead of infinite loop, here I am doing some big computation
            y = "nt"
        return(y)


import subprocess
elapsedTime = 0
p = subprocess.Popen(retval = fakeFxn("terminate"))
rc = p.poll()  #returncode
while (rc == None):
    sleep(5)
    elapsedTime = elapsedTime + 5
    if(elapsedTime <10):
        rc = p.poll()
        continue
    else:
        rc = "timeout"
        p.kill()
        break

Is this a good way to do it? Or is there any alternate way to do the same? I asked a related question here: Abruptly stop executing a command and continue to the next one

My actual function is the ``rpart` function of this post.

Upvotes: 2

Views: 322

Answers (2)

user2479509
user2479509

Reputation: 334

Not sure about through subprocess, but you should be able to do this with the help of multiprocessing and a wrapper function:

import time
from Queue import Empty
from multiprocessing import Process, Queue

def fakeFxn(val):
    if val == 'terminate':
        time.sleep(0.1)
        return 't'
    else:
        time.sleep(1000)
        return 'nt'

def ffWrapper(val, queue):
    retval = fakeFxn(val)
    queue.put(retval)

if __name__ == '__main__':
    q = Queue()
    p = Process(target=ffWrapper, args=('terminate', q))
    p.start()
    rc = ''
    try:
        rc = q.get(timeout=10)
    except Empty:
        print 'timeout'
    p.terminate()
    print rc

Upvotes: 2

dusty
dusty

Reputation: 573

subprocess should be used for executing external programs, not Python functions in one's module.

For your particular task you're better off using threading or multiprocessing modules. Your code could be rewritten like this (times out after two seconds):

from multiprocessing import Process
import time


def fake_function(arg):
    time.sleep(arg)
    print arg 


p = Process(target=fake_function, args=(10,))
p.start()
p.join(timeout=2)
p.terminate()

Upvotes: 0

Related Questions