1

私はPythonスクリプト(現在はos.system)からプログラムを実行しています。ただし、ある時点でプログラムがハングすることがあり、一定の時間間隔が経過してもstdoutまたはstderrに何も書き込まれない場合は、プログラムを強制終了したいと思います。このコードは通常、非常に長い時間(数時間から数日)実行され、まだ長い道のりが続く前にハングすることがあるため、プログラムの単純なタイムアウトは機能しません。

それsubprocess.Popenが道のりのようですが、これを行う方法についての良い例は見つかりませんでした。また、stdout/stderrをファイルに書き込みたいと思いました。

いくつかの例に基づいて、私は次のようなことを考えていました。

p = Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None)

while True:
    line = p.stdout.readline()
    outfile.write(line)
    # save current time or something, compare to time of
    # previous loop, if larger than timeout, kill process

whileしかし、タイムループを実装する方法と、プロセスが最終的に自動的に終了する(そしてハングしない)ときにが永久に実行されないようにする方法がわかりません。任意のポインタをいただければ幸いです。

4

2 に答える 2

2

signal.alarmを使用して、各行を受信した後にタイマーを設定しSIGALRM、最後の行から時間が経過していないかどうかを確認して処理してみてください。

于 2013-03-17T14:13:02.540 に答える
2

完全を期すために、提案されたコードを使用して、最終的に使用したコードを次に示しますsignal.alarm

import time
import shlex
import subprocess

logfile = open(log, 'w', 1)
# cmd is command to run
args = shlex.split(cmd)   # tokenise args list
p = subprocess.Popen(args, shell=False, bufsize=0, stdin=None,
                     stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

def _handler(signum, frame):
    print('Timeout of %s min reached, stopping execution' % timeout)
    p.kill()
    time.sleep(30)  # to ensure no ghost process is left running
    raise RuntimeError('Timeout')

signal.signal(signal.SIGALRM, _handler)
try:
    while True:
        signal.alarm(int(timeout))
        inline = p.stdout.readline()
        if not inline:
            break
        logfile.write(inline)
        signal.alarm(0)
except RuntimeError:
    logfile.close()
    return 0

p.communicate()   # wait for process to finish, get return code
logfile.close()
return p.returncode
于 2013-03-19T13:17:31.503 に答える