簡體   English   中英

如何在使用子進程時限制程序的執行時間?

[英]How to limit program's execution time when using subprocess?

我想使用子進程來運行程序,我需要限制執行時間。 例如,如果運行時間超過2秒,我想殺死它。

對於常見程序,kill()運行良好。 但是如果我嘗試運行/usr/bin/time something ,kill()就不能真正殺死程序。

我的下面的代碼似乎不能很好地工作。 該程序仍在運行。

import subprocess
import time

exec_proc = subprocess.Popen("/usr/bin/time -f \"%e\\n%M\" ./son > /dev/null", stdout = subprocess.PIPE, stderr = subprocess.STDOUT, shell = True)

max_time = 1
cur_time = 0.0
return_code = 0
while cur_time <= max_time:
    if exec_proc.poll() != None:
        return_code = exec_proc.poll()
        break
    time.sleep(0.1)
    cur_time += 0.1

if cur_time > max_time:
    exec_proc.kill()

如果您使用的是Python 2.6或更高版本,則可以使用多處理模塊。

from multiprocessing import Process

def f():
    # Stuff to run your process here

p = Process(target=f)
p.start()
p.join(timeout)
if p.is_alive():
    p.terminate()

實際上,多處理是此任務的錯誤模塊,因為它只是一種控制線程運行時間的方法。 您無法控制線程可能運行的任何子級。 正如奇點所暗示的那樣,使用signal.alarm是正常的方法。

import signal
import subprocess

def handle_alarm(signum, frame):
    # If the alarm is triggered, we're still in the exec_proc.communicate()
    # call, so use exec_proc.kill() to end the process.
    frame.f_locals['self'].kill()

max_time = ...
stdout = stderr = None
signal.signal(signal.SIGALRM, handle_alarm)
exec_proc = subprocess.Popen(['time', 'ping', '-c', '5', 'google.com'],
                             stdin=None, stdout=subprocess.PIPE,
                             stderr=subprocess.STDOUT)
signal.alarm(max_time)
try:
    (stdout, stderr) = exec_proc.communicate()
except IOError:
    # process was killed due to exceeding the alarm
finally:
    signal.alarm(0)
# do stuff with stdout/stderr if they're not None

在命令行中這樣做:

perl -e 'alarm shift @ARGV; exec @ARGV' <timeout> <your_command>

這將運行命令<your_command>並在<timeout>秒中終止它。

一個虛擬的例子:

# set time out to 5, so that the command will be killed after 5 second 
command = ['perl', '-e', "'alarm shift @ARGV; exec @ARGV'", "5"]

command += ["ping", "www.google.com"]

exec_proc = subprocess.Popen(command)

或者你可以使用signal.alarm ()如果你想用python但它是相同的。

我使用os.kill()但不確定它是否適用於所有操作系統。
偽代碼如下,請參閱Doug Hellman的頁面。

proc = subprocess.Popen(['google-chrome'])                                               
os.kill(proc.pid, signal.SIGUSR1)</code>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM