2013-09-24 13 views
13

Ich habe ein Python-Skript, das asynchrone Rückrufe von .NET Remoting behandelt. Diese Rückrufe werden in einem Dummy-Thread (Worker) ausgeführt. In meinem Callback-Handler muss ich eine Funktion aufrufen, die ich in meinem Skript definiert habe, aber ich muss die Funktion im Hauptthread ausführen.Ausführen von Python-Funktion im Haupt-Thread von Aufruf in Dummy-Thread

Der Haupt-Thread ist ein Remote-Client, der Befehle an einen Server sendet. Einige dieser Befehle führen zu asynchronen Rückrufen.

Grundsätzlich brauche ich das Äquivalent von .NETs Invoke-Methode. Ist das möglich?

+0

was macht der Haupt-Thread tun? Du musst es irgendwie signalisieren und es die Funktion aufrufen lassen. Wenn der Haupt-Thread normalerweise darauf wartet, dass etwas passiert, dann signalisieren Sie es. Wenn der Hauptthread die Verarbeitung ausführt, legen Sie die aufzurufende Funktion in eine Warteschlange, und der Hauptthread überprüft und verarbeitet die Warteschlange gelegentlich. – Claudiu

+0

Informationen zum Posten hinzugefügt. –

+0

Hmmm ... denke mehr .... wenn der Rückruf auftritt, während Main darauf wartet, dass der Server die Kontrolle von einem Anruf zurückgibt, gibt es keine Möglichkeit, Main dazu zu bringen, irgendetwas anderes zu tun, oder? –

Antwort

18

Sie möchten die Klasse Queue verwenden, um eine Warteschlange einzurichten, die Ihre Dummy-Threads mit Funktionen füllen und die Ihr Hauptthread belegt.

import Queue 

#somewhere accessible to both: 
callback_queue = Queue.Queue() 

def from_dummy_thread(func_to_call_from_main_thread): 
    callback_queue.put(func_to_call_from_main_thread) 

def from_main_thread_blocking(): 
    callback = callback_queue.get() #blocks until an item is available 
    callback() 

def from_main_thread_nonblocking(): 
    while True: 
     try: 
      callback = callback_queue.get(False) #doesn't block 
     except Queue.Empty: #raised when queue is empty 
      break 
     callback() 

Demo:

import threading 
import time 

def print_num(dummyid, n): 
    print "From %s: %d" % (dummyid, n) 
def dummy_run(dummyid): 
    for i in xrange(5): 
     from_dummy_thread(lambda: print_num(dummyid, i)) 
     time.sleep(0.5) 

threading.Thread(target=dummy_run, args=("a",)).start() 
threading.Thread(target=dummy_run, args=("b",)).start() 

while True: 
    from_main_thread_blocking() 

Drucke:

From a: 0 
From b: 0 
From a: 1 
From b: 1 
From b: 2 
From a: 2 
From b: 3 
From a: 3 
From b: 4 
From a: 4 

und blockiert dann für immer

+0

Sehr cool. Python macht das Delegieren und Speichern von Delegaten trivial. Ich weiß Ihre sehr ausführliche Antwort zu schätzen. –

+0

@ JimC: das ist ein Teil davon, warum es meine Lieblingssprache ist =). Prost – Claudiu

Verwandte Themen