在有限的时间内终止Python进程

时间:2014-01-11 22:41:52

标签: python multithreading process multiprocessing

使用Process:

查看这个简单的python代码
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"

我想我正在寻找像p.start(timeout)这样的函数。

我希望终止p进程,如果它没有在5秒内完成自我完成。我怎么能这样做?似乎没有这样的功能。

如果取消注释p.join(),则以下print行必须等待100秒,并且不能立即“立即打印”。但我希望它立即完成,以便p.join()具有被评论出来。

5 个答案:

答案 0 :(得分:1)

您可能需要查看that SO thread

基本上他们的解决方案是通过在单独的线程中运行进程来使用线程模块的超时功能。

答案 1 :(得分:1)

使用单独的线程启动进程,等待5秒,然后终止进程。同时主线程可以立即完成你想要的工作:

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"

答案 2 :(得分:0)

你是对的,子进程库中的Python 2.x中没有这样的函数。 但是,使用Python 3.3,您可以使用:

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

对于较旧的Python版本,您必须编写一个调用p.poll()的循环并检查返回码,例如:每秒一次。

从性能的角度来看,这(就像一般的民意调查一样)并不是最优的,但它总是取决于你的期望。

答案 3 :(得分:0)

尝试这样的事情:

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()  

基本上只是使用时间模块允许循环运行五秒然后继续,这假设超时以秒为单位。 虽然我已经指出,如果这与OP最初发布的代码一起使用,这将起作用,因为print是在与循环分开的第二个函数中,并且在调用此函数后立即执行。

答案 4 :(得分:0)

为什么不使用Process.join()的超时选项,如:

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()