Wie kann man die Zeit einschränken, die ein Programm unter Linux ausführt?

10

Ich habe mehrere Simulationen zu erledigen, von denen jede aufgerufen wird python simulate.py <parameter list>. Das Problem bei diesen Simulationen ist, dass einige von ihnen hängen bleiben, ohne sie zu beenden, was mich daran hindert, sie mit einem einfachen Skript im Batch auszuführen.

Was ich brauche, ist eine Art "Laufzeitbeschränkungs" -Befehl, der den Prozess nach einer bestimmten Zeit automatisch abbricht (vorzugsweise durch virtuelles Drücken von Strg + C , aber ich denke, einfaches Beenden reicht auch aus), wenn Der Prozess endete nicht von alleine.

Natürlich kann ich ein solches Skript selbst schreiben, aber ich vermute, dass jemand es bereits vor mir getan hat, sodass ich das Rad, mit dem ich Stunden verbringe ps, nicht neu erfinden timeund Handbücher schlagen muss.

Adam Ryczkowski
quelle

Antworten:

15

Mögliche Lösung Nr. 1

Verwenden Sie den timeoutBefehl:

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

Sie können dem timeoutBefehl auch eine Wache killhinzufügen, wenn er nach einiger Zeit nicht gestoppt wurde.

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

Dies wartet bis zu 20 Sekunden, nachdem der Prozess sleep 100hätte gestoppt werden sollen. Wenn er noch läuft, timeoutwird ihm ein killSignal gesendet.

Mögliche Lösung # 2

Ein alternativer, wenn auch riskanterer Weg wäre der folgende:

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

Diese Technik wurde bei Stack Overflow in einer Frage mit dem Titel gefunden: Begrenzen der Zeit, die ein Programm unter Linux ausführt . Speziell diese Antwort .

HINWEIS: Laut einem Kommentar von @mattdm kann die obige Methode riskant sein, da davon ausgegangen wird, dass seit Ihrem Prozess keine neuen Prozesse gestartet wurden. Es wurden also keine neuen PIDs zugewiesen. Vor diesem Hintergrund sollte dieser Ansatz wahrscheinlich nicht verwendet werden, sondern dient hier nur als Referenz für eine allgemeine Herangehensweise an das Problem. Die timeoutMethode ist die bessere Option der 2.

slm
quelle
Aber dann wird garantiert, dass das Skript immer die ganze Zeit dauert. In meinem Fall ist es nicht 1 Sekunde, sondern 15 Minuten.
Adam Ryczkowski
Aber die andere Lösung in dieser Frage sollte genau das sein, was ich brauche. Vielen Dank!
Adam Ryczkowski
2
Angenommen, die myProgram Fertigstellung erfolgt in kürzerer Zeit als sleep(keine unangemessene Annahme, da das Ziel darin besteht, eine maximal zulässige Laufzeit festzulegen). Sie senden dann ein Signal entweder an eine nicht vorhandene PID (kein wirklicher Schaden angerichtet) oder an einen zufälligen Prozess im System (möglicherweise tödlich).
Ein Lebenslauf
1
@ MichaelKjörling, danke für das Feeback. Ich habe meine Antwort gemäß demselben Kommentar aktualisiert, den das OP ebenfalls hinterlassen hat. Es sieht so aus, als ob der timeoutBefehl genau das tut, wonach er sucht, und darauf wartet, dass das OP auf meine Kommentare reagiert.
slm
@slm timeoutsollte die Lösung sein, die ich brauche. Ich
teste
4

Ich habe etwas Besseres gefunden als timeout: timelimit.

Es hat mehrere Vorteile; Zum einen kann der Benutzer die Ausführung manuell abbrechen, indem er "Strg + C" drückt.

Das timelimitProgramm ist im Debian-Repository verfügbar.

Adam Ryczkowski
quelle
1
Der Versuch, die Unterschiede zwischen Zeitlimit und Zeitlimit zu verstehen. Timeout kann mit Strg + C gestoppt werden. Was sind die anderen Vorteile?
slm
Nun, meine Auszeit kann nicht. Ich benutze Mint 14 (basierend auf Ubuntu Quantal).
Adam Ryczkowski
3

Sie können die CPU-Zeit und andere Dinge ulimiteinstellen, insbesondere für die CPU-Zeit:

$ ulimit -t 60      # limit to 60 seconds
$ program
RSFalcon7
quelle
Siehe diese U & L-Fragen und Antworten : unix.stackexchange.com/a/4666/7453 . @ Gilles gibt einen guten Überblick über die Verwendung von ulimit für diesen Zweck.
slm
0

Bash verwendet eine Variable $BASHPID, die in einer solchen Situation verwendet werden kann, zum Beispiel:

#!/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

Sie können das Argument im Aufruf in sleepin ändern do_face(), 100anstatt zu 10sehen, was passiert, wenn das Kind zu lange braucht, um seine Aufgaben zu erledigen. Ändern Sie einfach den Aufruf zum Einschlafen in do_face()einen Aufruf Ihrer ausführbaren Datei. Wenn dies zu lange dauert, wird er vom Skript beendet. 20In diesem Beispiel ist Sekunden der Grenzwert. Parameter können so implementiert werden, dass dies ein einfaches Skript zum Aufrufen wird und von einem anderen Skript im Batch oder was auch immer aufgerufen werden kann. Die Behandlung der PID-Dateien für jeden gleichzeitigen Prozess ist ein Problem, das behandelt werden muss. Verwenden Sie möglicherweise andere Unterverzeichnisse ...

NB: Unter GNU sleepkann Linux Gleitkomma-Argumente annehmen, um beispielsweise sleep 0.1eine Zehntelsekunde lang zu schlafen.

Overloaded_Operator
quelle