私はPythonで次のことを行う必要があります。私は、プロセス(サブプロセスモジュール?)を作成したいと思っています。そして、プロセスが正常に終了した場合、終了した時点から正確に続行する場合はPython:プロセスを実行し、1時間以内に終了しない場合は終了します。
- です。
- もしそうでなければ、プロセスは "スタックして" 1時間以内に終了しないで、それを強制終了して続行します(おそらくループで別の試行を与えます)。
これを達成する最もエレガントな方法は何ですか?
私はPythonで次のことを行う必要があります。私は、プロセス(サブプロセスモジュール?)を作成したいと思っています。そして、プロセスが正常に終了した場合、終了した時点から正確に続行する場合はPython:プロセスを実行し、1時間以内に終了しない場合は終了します。
これを達成する最もエレガントな方法は何ですか?
subprocess
モジュールはあなたの友人になります。プロセスを開始してPopen
オブジェクトを取得し、このような関数に渡します。これは、タイムアウト時にのみ例外が発生することに注意してください。必要に応じて例外をキャッチし、Popen
プロセスのkill()
メソッドを呼び出すことができます。
import time
def wait_timeout(proc, seconds):
"""Wait for a process to finish, or raise exception after timeout"""
start = time.time()
end = start + seconds
interval = min(seconds/1000.0, .25)
while True:
result = proc.poll()
if result is not None:
return result
if time.time() >= end:
raise RuntimeError("Process timed out")
time.sleep(interval)
(キルはところで、Pythonの2.6で新しく追加された)限り、あなたはプロセスのPIDを知っているようpsutilを使用して、これを行うには、少なくとも2通りの方法があります。プロセスを仮定 は、次のような作成されます。
import subprocess
subp = subprocess.Popen(['progname'])
...あなたはこのようなビジーループにその作成時間を取得することができます。
import psutil, time
TIMEOUT = 60 * 60 # 1 hour
p = psutil.Process(subp.pid)
while 1:
if (time.time() - p.create_time) > TIMEOUT:
p.kill()
raise RuntimeError('timeout')
time.sleep(5)
...あるいは単に、あなたがこれを行うことができます:また
import psutil
p = psutil.Process(subp.pid)
try
p.wait(timeout=60*60)
except psutil.TimeoutExpired:
p.kill()
raise
、あなたはそれでいる間、あなたは以下の余分のAPIに興味があるかもしれません:
>>> p.status()
'running'
>>> p.is_running()
True
>>>
私も同様の質問があり、この回答が見つかりました。ドキュメントからのpython信号ライブラリ https://docs.python.org/2/library/signal.html
:
import signal, os
def handler(signum, frame):
print 'Signal handler called with signal', signum
raise IOError("Couldn't open device!")
# Set the signal handler and a 5-second alarm
signal.signal(signal.SIGALRM, handler)
signal.alarm(5)
# This open() may hang indefinitely
fd = os.open('/dev/ttyS0', os.O_RDWR)
signal.alarm(0) # Disable the alarm
あなたが産卵したかったので、ちょうど完全を期すために、私はどのように一定時間後にハングプロセスを終了させるもう一つの方法を追加したいですとにかく新しいプロセスですが、これはあなたの問題に対する最良の解決策ではないかもしれません。
いいえ、パッシブなやり方は、threading.Timerを使用してコールバック機能を設定することです。
from threading import Timer
# execute the command
p = subprocess.Popen(command)
# save the proc object - either if you make this onto class (like the example), or 'p' can be global
self.p == p
# config and init timer
# kill_proc is a callback function which can also be added onto class or simply a global
t = Timer(seconds, self.kill_proc)
# start timer
t.start()
# wait for the test process to return
rcode = p.wait()
t.cancel()
時間内に処理が完了すると、wait()は終了し、ここでコードが続行され、cancel()はタイマーを停止します。一方、タイマーがなくなり、別のスレッドでkill_procを実行すると、wait()もここで続行され、cancel()は何も行いません。 rcodeの値によって、タイムアウトしたかどうかを知ることができます。最も単純なkill_proc:(もちろん何でもできる)
def kill_proc(self):
os.kill(self.p, signal.SIGTERM)