2015-12-01 9 views
7

Die Situation: Ich habe eine Website, die Menschen die Ausführung von beliebigem Code in einer anderen Sprache (speziell ein Esolang ich erstellt), mit einem Python-Interpreter auf einem Shared-Hosting-Server ermöglicht. Ich führe diesen Code in einem separaten Prozess aus, der ein Zeitlimit von 60 Sekunden hat.Wie töte ich automatisch einen Prozess, der zu viel Speicher mit Python verwendet?

Das Problem: Sie können Sachen wie (Python gleichwertig) 10**(10**10) tun, die schnell viel mehr Speicher verbraucht, als ich mir zugeteilt habe. Es blockiert anscheinend auch Apache - oder es dauert zu lange, um darauf zu antworten - also muss ich es neu starten.

Ich habe gesehen this question, aber die gegebene Antwort verwendet Perl, die ich überhaupt nicht kenne, daher möchte ich eine Antwort in Python. Das OS ist aber auch Linux.

Insbesondere möchte ich die folgenden Eigenschaften:

  1. Läuft automatisch
  2. Kraft-tötet jeder Prozess, der einige Speicherlimit wie 1MB oder 100MB von meinem Code
  3. tötet jeden Prozess, der mehr hervorgebracht übersteigt, als 24 Stunden alt

ich benutze dieses Stück Code (in einer Django-view), um den Prozess zu erstellen und ausführen (proxy_prgm ein Manager ist, so kann ich ret Rieve Daten aus dem Programm, das die esolang Code ist Interpretation):

prgmT[uid] = multiprocessing.Process(
    target = proxy_prgm.runCatch, 
    args = (steps,), 
    name="program run") 

prgmT[uid].start() 
prgmT[uid].join(60) #time limit of 1 minute 

if prgmT[uid].is_alive(): 
    prgmT[uid].terminate() 
    proxy_prgm.stop() 

Wenn Sie weitere Informationen benötigen, zögern Sie nicht, mir zu sagen, was in bearbeiten (oder fragen Sie mich Fragen).

+2

Einige Ideen: Sie könnten ulimit verwenden, um den maximalen Speicher des erzeugten Prozesses festzulegen. Sie können psutil verwenden, um die Speicherbelegung zu überwachen und sie zu beenden, wenn sie außer Kontrolle gerät. – dbn

+1

Ich stimme zu, dass Sie das "ulimit" Ihres Betriebssystems verwenden sollten, um Ressourcen zu überwachen. Es kann verwendet werden, um sicherzustellen, dass Sie keine anderen Ressourcen wie Dateisperren verbrauchen. – Maciek

+0

Nur eine Randnotiz - eine Ansicht scheint mir nicht der richtige Ort für solchen Code zu sein. –

Antwort

3

Ein anderer Ansatz, der funktionieren könnte; unter Verwendung resource.setrlimit() (mehr Details in this other StackOverflow answer). Es scheint, dass Sie damit ein Speicherlimit für einen Prozess und seine Subprozesse festlegen können. Sie müssen herausfinden, wie Sie umgehen müssen, wenn das Limit erreicht wird. Ich habe keine persönlichen Erfahrungen damit, aber hoffentlich würde Apache davon abhalten, dich zu blockieren.