2017-07-20 3 views
14

Dites que j'ai une fonction python longue qui ressemble à ceci?Comment faire pour temporiser un programme en cours d'exécution en utilisant rxpython?

import random 
import time 
from rx import Observable 
def intns(x): 
    y = random.randint(5,10) 
    print(y) 
    print('begin') 
    time.sleep(y) 
    print('end') 
    return x 

Je veux être en mesure de définir un délai de 1000ms.

Donc je suis dong quelque chose comme, en créant un observable et en le mappant à travers le calcul intense ci-dessus.

a = Observable.repeat(1).map(lambda x: intns(x)) 

Maintenant, pour chaque valeur émise, si elle prend plus de 1000ms je veux mettre fin à l'observable, dès que j'atteins 1000ms en utilisant on_error ou on_completed

a.timeout(1000).subscribe(lambda x: print(x), lambda x: print(x)) 

déclaration ci-dessus ne délai obtenir, et appelle on_error, mais il finit de calculer le calcul intense et revient seulement ensuite aux instructions suivantes. Existe-t-il une meilleure façon de le faire?

La dernière instruction affiche les éléments suivants

8 # no of seconds to sleep 
begin # begins sleeping, trying to emit the first value 
Timeout # operation times out, and calls on_error 
end # thread waits till the function ends 

L'idée est que si une timesout de fonction particulière, je veux être en mesure de poursuivre mon programme, et d'ignorer le résultat. Je me demandais si la fonction intns a été faite sur un thread séparé, je suppose que le thread principal continue d'exécution après le délai d'expiration, mais je veux toujours arrêter de calculer la fonction intns sur un thread, ou le tuer en quelque sorte.

Répondre

0

Vous pouvez le faire partiellement en utilisant le thread Bien qu'il n'y ait pas de manière spécifique de tuer un thread dans python, vous pouvez implémenter une méthode pour marquer le thread à la fin.

Cela ne fonctionnera pas si le fil est en attente d'autres ressources (dans votre cas, vous simulé un code en cours d'exécution « long » par une attente aléatoire)

Voir aussi Is there any way to kill a Thread in Python?

+0

Un exemple montrant ce comportement serait assez agréable – Adonis

+0

S'il vous plaît voir la nouvelle réponse –

0

De cette façon, il fonctionne:

import random 
import time 
import threading 
import os 

def intns(x): 
    y = random.randint(5,10) 
    print(y) 
    print('begin') 
    time.sleep(y) 
    print('end') 
    return x 


thr = threading.Thread(target=intns, args=([10]), kwargs={}) 
thr.start() 
st = time.clock(); 
while(thr.is_alive() == True): 
    if(time.clock() - st > 9): 
     os._exit(0) 
+0

Il fonctionne, mais il est en aucun cas en rapport avec le paquet 'rx' qui est au cœur de la question – Adonis

+0

Pas vraiment, il didn ne demande pas comment le faire avec rx, il a juste dit qu'il a essayé de le faire avec rx –

+0

vrai, je n'ai pas remarqué le 'rx' dans 'rxpython' de toute façon je pense qu'il ne s'intéressait pas vraiment au paquet rx –

0

Voici un exemple pour le délai

import random 
import time 
import threading 

_timeout = 0 

def intns(loops=1): 
    print('begin') 
    processing = 0 
    for i in range(loops): 
     y = random.randint(5,10) 
     time.sleep(y) 
     if _timeout == 1: 
      print('timedout end') 
      return 
     print('keep processing') 
    return 

# this will timeout 
timeout_seconds = 10 
loops = 10 

# this will complete 
#timeout_seconds = 30.0 
#loops = 1 

thr = threading.Thread(target=intns, args=([loops]), kwargs={}) 
thr.start() 
st = time.clock(); 
while(thr.is_alive() == True): 
    if(time.clock() - st > timeout_seconds): 
     _timeout = 1 

thr.join() 
if _timeout == 0: 
    print ("completed") 
else: 
    print ("timed-out") 
+1

et comment suggérez-vous de le combiner avec rx? – ffeast

+0

c'est une solution de contournement générique. La fonction Observable permet de définir une temporisation et d'effectuer une vérification entre les tâches si elle doit expirer et retourner la valeur on_error. Cela a la limitation indiquée ci-dessus sur où le traitement d'attente/temps est –

0

Ce qui suit est une classe qui peut être appelée à l'aide with timeout() :

Si le bloc sous le code fonctionne plus longtemps que le temps spécifié, une TimeoutError est élevée.

import signal 

class timeout: 
    # Default value is 1 second (1000ms) 
    def __init__(self, seconds=1, error_message='Timeout'): 
     self.seconds = seconds 
     self.error_message = error_message 
    def handle_timeout(self, signum, frame): 
     raise TimeoutError(self.error_message) 
    def __enter__(self): 
     signal.signal(signal.SIGALRM, self.handle_timeout) 
     signal.alarm(self.seconds) 
    def __exit__(self, type, value, traceback): 
     signal.alarm(0) 

# example usage 
with timeout() : 
    # infinite while loop so timeout is reached 
    while True : 
     pass 

Si je comprends bien votre fonction, voici ce que votre implémentation ressemblerait à ceci:

def intns(x): 
    y = random.randint(5,10) 
    print(y) 
    print('begin') 
    with timeout() : 
     time.sleep(y) 
    print('end') 
    return x 
0

Vous pouvez utiliser time.sleep() et faire une boucle while pour le temps.horloge()