Linuxでプログラムを実行する時間を制限する方法は?


10

実行するシミュレーションがいくつかあり、それぞれをで呼び出しますpython simulate.py <parameter list>。これらのシミュレーションの問題は、一部のシミュレーションが終了せずにハングするため、単純なスクリプトでそれらをバッチで実行できないことです。

私が必要とするのは、指定された時間が経過した後、プロセスを自動的に強制終了する(好ましくはCtrl + Cを押して、できれば単純な強制終了でも同様だと思う)何らかの形式の「実行時制約」コマンドです。プロセスはそれ自体で優雅に終了しませんでした。

もちろん私は自分でそのようなスクリプトを書くことができますが、誰かが私の前ですでにそれを行っているのではないかと思うのでpstimeとbashのマニュアルで時間を費やすホイールを作り直す必要はありません。

回答:


15

可能な解決策#1

次のtimeoutコマンドを使用します。

$ date
Mon May  6 07:35:07 EDT 2013
$ timeout 5 sleep 100
$ date
Mon May  6 07:35:14 EDT 2013

一定時間経過しても停止していない場合は、timeoutコマンドとkillプロセスの両方にガードを設定できます。

$ date
Mon May  6 07:40:40 EDT 2013
$ timeout -k 20 5 sleep 100
$ date
Mon May  6 07:40:48 EDT 2013

これは、プロセスsleep 100が停止してから最大20秒待機します。まだ実行中の場合timeoutは、killシグナルを送信します。

考えられる解決策#2

別の方法ですが、より危険な方法は次のとおりです。

./myProgram &
sleep 1
kill $! 2>/dev/null && echo "myProgram didn't finish"

Stack Overflowのタイトルの質問でこのテクニックを見つけました:Linuxでプログラムを実行する時間を制限する。具体的にはこの答え

注: @mattdmによって残されたコメントによれば、上記の方法は、プロセス以降に開始された新しいプロセスがないことを前提としているため、リスクを伴う可能性があります。そのため、新しいPIDは割り当てられていません。このため、このアプローチはおそらく使用すべきではありませんが、ここでは問題に対する一般的なアプローチの参照としてのみ使用しています。このtimeout方法は、2のより良いオプションです。


ただし、スクリプトが常にその時間を費やすことが保証されます。私の場合、1秒ではなく15分です。
Adam Ryczkowski 2013年

しかし、その質問で見つかった他の解決策は、まさに私が必要とするものでなければなりません。ありがとう!
Adam Ryczkowski 2013年

2
myProgramは、より短い時間で終了すると仮定しますsleep(目標は最大許容ランタイムを設定することなので、不合理な仮定ではありません)。次に、存在しないPID(実際には害はありません)またはシステム上の任意のランダムプロセス(致命的となる可能性があります)に信号を送信します。
CVn 2013年

1
@MichaelKjörling、フィードバックをありがとう。OPが残したのと同じコメントごとに私の回答を更新しました。timeoutコマンドは、OPが私のコメントに応答するのを待って、彼が探しているものを正確に実行しているように見えます。
slm

@slm timeoutは私が必要とするソリューションでなければなりません。私は現在それをテストしています
アダム・リツコウスキー2013年

4

私はもう少し良いものを見つけましたtimeouttimelimit

これにはいくつかの利点があります。1つは、ユーザーが「Ctrl + C」を押すことで実行を手動で中止できることです。

timelimitプログラムは、Debianのリポジトリで利用可能です。


1
b / w timelimitとtimeoutの違いを理解しようとしています。タイムアウトはCtrl + Cで停止できます。他の利点は何ですか?
slm

まあ、私のタイムアウトはできません。私はMint 14(Ubuntu Quantalベース)を使用しています。
アダムRyczkowski 2013年

3

ulimit特にCPU時間については、CPU時間などをで調整できます。

$ ulimit -t 60      # limit to 60 seconds
$ program

このU&L Q&Aを参照してください:unix.stackexchange.com/a/4666/7453。@Gillesは、この目的でのulimitの使用の概要を示しています。
slm

0

Bashは、$BASHPIDそのような状況で使用できるという変数を使用します。次に例を示します。

#!/bin/bash
do_face() {
    local parent=$1
    echo $BASHPID > pid
    sleep 10
    echo "Killing parent $parent"
    kill $parent
}

ME=$BASHPID
eval $(echo "do_face $ME &")
sleep 20 && kill $(cat pid) && echo "killed child $(cat pid)"
exit 1

あなたはへの呼び出しで引数を変更することができますsleepdo_face()する100代わりに10、子供が自分の家事を行うために要する時間が長すぎると何が起こるか参照してください。スリープインdo_face()するための呼び出しを実行可能ファイルへの呼び出しに変更するだけです。時間がかかりすぎると、スクリプトによって強制終了され20ます。この例では、秒数が制限値です。パラメータを実装して、これを呼び出す簡単なスクリプトにして、別のスクリプトからバッチなどで呼び出すことができるようにすることができます。各並行プロセスのpidファイルの処理は、処理する必要がある問題です。おそらく、異なるサブディレクトリを使用してください...

注意:GNU Linuxでは、10秒間スリープするsleepなどの浮動小数点引数を取ることができますsleep 0.1

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.