2016-04-17 11 views
9

My Twisted Arbeiten Programm, aber jetzt habe ich ein Problem mit einem meiner Reaktoren nicht vorrangig auf die anderen übergeben. Ich möchte, dass der controlListener-Reaktor eine Iteration ausführt und dann die Priorität an den Druckreaktor übergibt.Verdrehte Logik Fehler

#Random class as proof of concept 
class printStuffs(object): 
     print "counting " 
     printerCount = 0 
     def count(self): 
      self.printerCount = self.printerCount + 1 
      print ("the counter is at " + str(self.printerCount)) 

    ########################################################################## 
    ## The control listneer class is designed to kill given reactor threads ## 
    ## on demand from something once it recieves a signal it is supposed ## 
    ## to do one ieteration then release         ## 
    ########################################################################## 

    class controlListener(object): 
      counter = 20 
      def count(self): 
       if self.counter == 0: 
        print "Killing Process" 
        reactor.stop() 
       else: 
        print self.counter, '...' 
        self.counter -= 1 
        reactor.callLater(1, self.count) 

from twisted.internet import reactor 

print "Printing random stuff" 
reactor.callWhenRunning(printStuffs().count) 

print "Intializing kill listner" 
reactor.callWhenRunning(controlListener().count) 
reactor.run() 

print "Process killed" 

Hier ist die Ausgabe

Printing random stuff 
    Intializing kill listner 
    the counter is at 1 
    20 ... 
    19 ... 
    18 ... 
    17 ... 
    16 ... 
    15 ... 
    14 ... 
    13 ... 
    12 ... 
    11 ... 
    10 ... 
    9 ... 
    8 ... 
    7 ... 
    6 ... 
    5 ... 
    4 ... 
    3 ... 
    2 ... 
    1 ... 
    Killing Process 
    Process killed 

ich es will, etwas tun wie

the counter is at 1 
20 ... 
the counter is at 2 
the counter is at 3 
19 ... 

usw.

Irgendwelche Ideen?

+2

ich nie verdreht verwendet, aber es könnte sein, dass 'printStuffs.count()' 'einfach nicht nicht verwendet reactor.callLater()' selbst neu zu planen wie 'controlListener.count()' tut? – Norman

+0

Sie haben es, wenn Sie den Kredit kopieren Sie Ihre Post in eine tatsächliche Antwort wollen, und ich werde es vergeben. –

+1

Sie haben bereits eine Antwort erhalten, aber ich möchte nur feststellen, dass es ein LoopingCall in verdreht ist (https://twistedmatrix.com/documents/current/api/twisted.internet.task.LoopingCall.html), der es ermöglicht Sie können wiederholte Anrufe nicht manuell neu skalieren. –

Antwort

6

Sie haben einfach vergessen printStuffs.count() sich selbst zu planen, indem Sie reactor.callLater() verwenden, wie controlListener.count() tut.

class printStuffs(object): 
    printerCount = 0 
    def count(self): 
     self.printerCount = self.printerCount + 1 
     print ("the counter is at " + str(self.printerCount)) 
     reactor.callLater(1, self.count) 

Auch in der Klassendefinition eine print-Anweisung (print "counting") direkt setzen und nicht in einer Funktion bewirkt, dass es richtig ausgeführt wird, wenn die Python-Interpreter die Klassendefinition lesen. Das ist irreführend, weil die Nachricht "Zählen" sagt, aber zu diesem Zeitpunkt passiert (noch) nichts.


Dies könnte einer dieser Fehler sein, wenn man es nicht sieht, sieht man es nicht.
Das warum für einige wichtige Funktionen oder Threads ist, ich Trace-Logging-Anweisungen zu meinem Code hinzufügen, die mir sagen, wenn eine Funktion aufgerufen wird, oder wenn ein Thread und beginnt, wenn es endet. Dies ist besonders nützlich für Funktionen, die aufgrund eines Fehlers abgebrochen werden können, und für Threads, von denen Sie erwarten, dass sie die meiste Zeit ausgeführt werden.

Dies ist, wie Sie dieses Muster zu Ihrem Beispiel anpassen konnte:

class printStuffs(object): 
    printerCount = 0 
    def count(self): 
     try: 
      ##print "Entering printStuffs.count()." 
      self.printerCount = self.printerCount + 1 
      print ("The counter is at " + str(self.printerCount)) 
      # Run again later. 
      reactor.callLater(1, self.count) 
     except: 
      # We won't run again later. 
      print "Error in printStuffs.count(), won't run again:", sys.exc_info()[0] 
      # Don't swallow the exception. 
      raise 
     finally: 
      ##print "Leaving printStuffs.count()." 

Natürlich ist dies für Ihr Beispiel zu viel des Guten wäre, aber Ihre echten Code ist wahrscheinlich komplexer.

Wenn Ihre Programme erhalten größer und komplexer, auf diese Weise mit Protokollierung hilft Ihnen, sicherzustellen, dass die grundlegenden Prozesse in Ihrem Programm wie vorgesehen arbeiten.