476 votes

Délai d’attente sur un appel de fonction Python

J’appelle une fonction en Python qui je sais peut caler et me forcer à redémarrer le script. Comment appeler la fonction ou quoi j’ai envelopper dans afin que si cela prend plu de 5 secondes le script annule et fait quelque chose d’autre.

Merci

320voto

piro Points 4848

Vous pouvez utiliser le signal de paquet, si vous êtes en cours d'exécution sur UNIX:

In [1]: import signal

# Register an handler for the timeout
In [2]: def handler(signum, frame):
   ...:     print "Forever is over!"
   ...:     raise Exception("end of time")
   ...: 

# This function *may* run for an indetermined time...
In [3]: def loop_forever():
   ...:     import time
   ...:     while 1:
   ...:         print "sec"
   ...:         time.sleep(1)
   ...:         
   ...:         

# Register the signal function handler
In [4]: signal.signal(signal.SIGALRM, handler)
Out[4]: 0

# Define a timeout for your function
In [5]: signal.alarm(10)
Out[5]: 0

In [6]: try:
   ...:     loop_forever()
   ...: except Exception, exc: 
   ...:     print exc
   ....: 
sec
sec
sec
sec
sec
sec
sec
sec
Forever is over!
end of time

# Cancel the timer if the function returned before timeout
# (ok, mine won't but yours maybe will :)
In [7]: signal.alarm(0)
Out[7]: 0

10 secondes après l'appel alarm.alarm(10), le gestionnaire est appelé. Cela soulève une exception que vous pouvez intercepter dans le code Python.

Ce module n'est pas de bien jouer avec les threads (mais alors, qui le fait?)

Notez que depuis que nous soulever une exception lorsque le délai d'attente se produit, elle peut se retrouver pris et ignorés à l'intérieur de la fonction, par exemple de l'une de ces fonctions:

def loop_forever():
    while 1:
        print 'sec'
        try:
            time.sleep(10)
        except:
            continue

225voto

ATOzTOA Points 9045

Vous pouvez utiliser `` pour faire exactement cela.

Code

65voto

Alex Points 2686

J’ai une autre proposition qui est pure (avec la même API que la suggestion de thread) et semble fonctionner amende (issu des suggestions sur ce fil)

3voto

Jason Baker Points 56682

Si ce n'est une sorte de réseau ou de l'opération de fichier, vous pouvez également envisager l'utilisation non bloquantes IO. Cela peut être une meilleure option si vous faites beaucoup de ces types d'opérations à la fois (sinon, vous pouvez la tourbière de votre système vers le bas assez rapidement avec un grand nombre de threads). Ici's un socket howto qui couvre non bloquantes IO (dans le contexte de l'exploitation des réseaux).

Le revers de la médaille? Eh bien, il peut être une douleur au programme. Parfois même plus que simplement à l'aide d'un fil.

1voto

Claudiu Points 58398

Ce qu’yabcok dit - commencer un nouveau thread pour appeler la fonction. Dans le thread d’origine, sommeil pendant 5 secondes, puis terminer le thread fonction si elle n’a pas déjà terminé.

Il est peut-être préférable à votre problème ? Pourquoi la fonction prendrait plue de 5 secondes ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X