2013-02-17 12 views
15

Chciałbym zadzwonić pod numer foo(n), ale zatrzymaj go, jeśli działa przez ponad 10 sekund. Jaki jest dobry sposób na zrobienie tego?Kod zatrzymania po okresie czasu

Widzę, że teoretycznie mógłbym zmodyfikować foo, aby okresowo sprawdzać, jak długo działa, ale wolałbym tego nie robić.

+1

Co masz w środku 'foo'? Czy to pętla? Czy zamierzasz uruchomić 'foo' jako inny wątek? – ATOzTOA

+0

Naprawdę rozważam modyfikowanie 'foo', ale poza tym zobacz to pytanie: http://stackoverflow.com/questions/492519/timeout-on-a-python-function-call lub this: http://stackoverflow.com/questions/4158502/python-kill-or-terminate-subprocess-when-timeout –

+0

@ATOzTOA To skomplikowany fragment kodu wykonujący skomplikowane obliczenia. Nie napisałem tego kodu. – felipa

Odpowiedz

24

Proszę bardzo:

import multiprocessing 
import time 

# Your foo function 
def foo(n): 
    for i in range(10000 * n): 
     print "Tick" 
     time.sleep(1) 

if __name__ == '__main__': 
    # Start foo as a process 
    p = multiprocessing.Process(target=foo, name="Foo", args=(10,)) 
    p.start() 

    # Wait 10 seconds for foo 
    time.sleep(10) 

    # Terminate foo 
    p.terminate() 

    # Cleanup 
    p.join() 

To będzie czekać 10 sekund foo a następnie zabić go.

Aktualizacja

Zakończenie procesu tylko wtedy, gdy jest uruchomiony.

# If thread is active 
if p.is_alive(): 
    print "foo is running... let's kill it..." 

    # Terminate foo 
    p.terminate() 

Aktualizacja 2: Zalecane

Zastosowanie join z timeout. Jeśli foo zakończy się przed upływem limitu czasu, main może kontynuować.

# Wait a maximum of 10 seconds for foo 
# Usage: join([timeout in seconds]) 
p.join(10) 

# If thread is active 
if p.is_alive(): 
    print "foo is running... let's kill it..." 

    # Terminate foo 
    p.terminate() 
    p.join() 
+0

Dzięki! Idealnie chciałbym zabić tylko ten proces, jeśli jeszcze się nie zakończył. Czy jest sposób, aby to sprawdzić? – felipa

+0

@felipa Tak, sprawdź moją zaktualizowaną odpowiedź ... – ATOzTOA

+0

Dziękuję bardzo (chociaż 'timeout' nie pojawia się w twojej odpowiedzi). Jest to bardzo pomocne i informacyjne. Jeśli ktokolwiek kiedykolwiek przegłosuje to pytanie (powiązane pytania nie mają tak przydatnych odpowiedzi, jak się wydaje), to oczywiście przegłosuję. Obecnie nie wydaje mi się. – felipa

2
import signal 

#Sets an handler function, you can comment it if you don't need it. 
signal.signal(signal.SIGALRM,handler_function) 

#Sets an alarm in 10 seconds 
#If uncaught will terminate your process. 
signal.alarm(10) 

Timeout nie jest bardzo precyzyjny, ale może to zrobić, jeśli nie trzeba ekstremalną precyzją.

Innym sposobem jest użycie modułu zasobów i ustawienie maksymalnego czasu procesora.

+0

Co możesz nieco powiększyć, aby pokazać, jak kończy się na przykład funkcja 'foo', a nie cały skrypt Pythona? Chcę, aby mój skrypt działał dalej, tylko po to, aby wywołać 'foo' do przekroczenia limitu czasu po 10 sekundach. – felipa

+0

Napisz do tego funkcję obsługi funkcji, na przykład w każdej iteracji sprawdzania funkcji dla zmiennej globalnej i zmień tę zmienną w procedurze obsługi sygnału. – LtWorf

+0

@LtWorf OP już powiedział, że funkcja jest złożona, a nie pojedyncza pętla. Tak więc to nie zadziała. – ATOzTOA

Powiązane problemy