0

次の問題があります。

Python スクリプトで bash スクリプトを実行する必要があります。bash スクリプトがたとえば 10 秒以上実行されている場合は、それを強制終了する必要があります。これは私がこれまでに持っているものです:

cmd = ["bash", "script.sh", self.get_script_path()]
process = subprocess.Popen(cmd)

time.sleep(10)  # process running here...

procinfo = psutil.Process(process.pid)
children = procinfo.children(recursive=True)
for child in children:
    os.kill(child.pid, signal.SIGKILL)

私が恐れているのは、このシナリオです。bash スクリプトは 1 秒で終了し、その PID を解放し、システムは PID を別のプロセスに渡します。10 秒後、スクリプトに属していると思われる PID を強制終了しますが、そうではなく、他のプロセスを強制終了します。スクリプトは必要なので、ルートとして実行する必要がありますchroot

何か案は?

4

3 に答える 3

2

既に使用しているので、モジュールpsutilへの呼び出しを への呼び出しに置き換えることをお勧めします。このクラスは と同じインターフェイスを持ちますが、 のすべての機能を提供します。subprocesspsutil.Popensubprocess.Popenpsutil.Process

また、少なくとも と を含む多くのメソッドについて、ライブラリpsutilが PID の再利用を事前にチェックすることにも注意してください( のドキュメントを参照してください)。terminatekillProcess

これは、次のコードを意味します。

cmd = ["bash", "script.sh", self.get_script_path()]
process = psutil.Popen(cmd)

time.sleep(10)  # process running here...

children = process.children(recursive=True)
for child in children:
    child.terminate()   # try to close the process "gently" first
    child.kill()

childrenのドキュメントには次のように記載されていることに注意してください。

children(recursive=False)

Processこのプロセスの子をオブジェクトのリストとして返し、PID が再利用されたかどうかを事前にチェックします。

要約すると、これは次のことを意味します。

  1. ライブラリチェックを呼び出すとchildrenpsutilたまたま同じpidを持つプロセスではなく、正しいプロセスの子が必要であることを確認します
  2. terminateまたはライブラリを呼び出すkillと、同じpidを持つランダムなプロセスではなく、子プロセスを強制終了していることを確認します。
于 2016-08-28T08:15:52.667 に答える
0

timeoutコマンドはあなたにぴったりだと思います。ドキュメントページから:

あらすじ

timeout [OPTION] NUMBER[SUFFIX] COMMAND [ARG]...
timeout [OPTION]


説明

COMMAND を開始し、NUMBER 秒後にまだ実行中の場合は強制終了します。SUFFIX は、秒を表す「s」(デフォルト)、分を表す「m」、時間を表す「h」、または日を表す「d」です。

-s--signal = SIGNAL
タイムアウト時に送信されるシグナルを指定します。
        SIGNALは、'HUP' のような名前または番号です。
        シグナルのリストについては、「kill -l」を参照してください

に依存するtimeoutことで、PID の再利用や競合状態などの厄介な詳細について心配する必要がなくなります。これらの懸念は、この標準の Unix ユーティリティにうまくカプセル化されています。もう 1 つの利点は、サブプロセスによる早期終了時にスクリプトがすぐに実行を再開することです。不必要に 10 秒間スリープすることはありません。

bash でのデモ:

timeout -s9 10 sleep 11; echo $?;
## Killed
## 137
timeout -s9 10 sleep 3; echo $?;
## 0

Python でのデモ:

import subprocess;
subprocess.Popen(['timeout','-s9','10','sleep','11']).wait();
## -9
subprocess.Popen(['timeout','-s9','10','sleep','3']).wait();
## 0
于 2016-08-28T08:03:28.830 に答える
-3

プロセスを停止するために、ubuntu でコマンド stop process_name を使用しています。役に立ちますように。

于 2016-08-28T07:19:54.707 に答える