1

Take a look at this simple python code with Process:

from multiprocessing import Process
import time

def f(name):
    time.sleep(100)
    print 'hello', name

if __name__ == '__main__':
    p = Process(target=f, args=('bob',))
    p.start()#Has to be terminated in 5 seconds
    #p.join()
    print "This Needs to be Printed Immediately"

I guess I am looking for a function like p.start(timeout).

I want to terminate the p process if it has not self-finished in like 5 seconds. How can I do that? There seems to be no such function.

If p.join() is uncommented, the following print line will have to wait 100 seconds and can not be 'Printed Immediately'.But I want it be done immediately so the p.join() has to be commented out.

James King
  • 1,574
  • 4
  • 19
  • 28
  • It's probably not the nicest option, but if you really want a process, you should be able to abort it by sending a signal to the process (since you have access to its PID). – Siegfried Gevatter Jan 11 '14 at 23:37

5 Answers5

1

You might want to take a look at that SO thread.

basically their solution is to use the timeout capability of the threading module by running the process in a separate thread.

Community
  • 1
  • 1
astreal
  • 3,383
  • 21
  • 34
1

Use a separate thread to start the process, wait 5 seconds, then terminate the process. Meanwhile the main thread can do the work you want to happen immediately:

from multiprocessing import Process
import time
import threading 

def f(name):
    time.sleep(100)
    print 'hello', name

def run_process_with_timeout(timeout, target, args):
    p = Process(target=target, args=args)
    p.start()
    time.sleep(timeout)
    p.terminate()

if __name__ == '__main__':
    t = threading.Thread(target=run_process_with_timeout, args=(5,f,('bob',)))
    t.start()
    print "This Needs to be Printed Immediately"
Alp
  • 2,766
  • 18
  • 13
0

You are right, there is no such function in Python 2.x in the subprocess library. However, with Python 3.3 you can use:

p = subprocess.Popen(...)
try:
    p.wait(timeout=5)
except TimeoutError:
    p.kill()

With older Python versions, you would have to write a loop that calls p.poll() and checks the returncode, e.g. once per second.

This is (like polling in general) not optimal from performance point-of-view, but it always depends on what you expect.

hvb
  • 2,484
  • 1
  • 10
  • 13
0

Try something like this:

def run_process_with_timeout(timeout, target, args):
    p = Process(target=target, args=args)
    running = False
    second = int(time.strftime("%S"))
    if second+timeout > 59:
        second = (second+timeout)-60
    else:
        second = second+timeout
    print second
    while second > int(time.strftime("%S")):
        if running == False:
            p.start()
            running = True
    p.terminate()  

basically just using the time module to allow a loop to run for five seconds and then moving on, this assumes timeout is given in seconds. Though I'd point out that if this was used with the code the OP originally posted, this would work, as print was in a second function separate from the loop and would be carried out immediately after calling this function.

Christopher
  • 169
  • 2
  • 6
0

Why not use the timeout option of Process.join(), as in:

import sys
...
if __name__ == '__main__':
    p = Process(target=f, args=('bob',))
    p.start()#Has to be terminated in 5 seconds
    # print immediately and flush output 
    print "This Needs to be Printed Immediately"
    sys.stdout.flush()
    p.join(5)
    if p.is_alive():
       p.terminate()
miraculixx
  • 10,034
  • 2
  • 41
  • 60
  • You solved this particular problem, bu what if the `print` line is actually a `return` line? Then your code will not work. – James King Jan 12 '14 at 19:23
  • In your question you stated that you want this `print`ed immediately, so that's what I referred to. If you want to exit the program and still automatically kill the proess after 5 seconds you will have to start a daemon process that does the p.join(5) and p.terminate() if necessary. See http://docs.python.org/2/library/multiprocessing.html#multiprocessing.Process.daemon – miraculixx Jan 18 '14 at 03:41