26

.NET Remoting からの非同期コールバックを処理する Python スクリプトがあります。これらのコールバックは、ダミー (ワーカー) スレッドで実行されます。コールバック ハンドラー内から、スクリプトで定義した関数を呼び出す必要がありますが、その関数をメイン スレッドで実行する必要があります。

メイン スレッドは、コマンドをサーバーに送信するリモート クライアントです。これらのコマンドの一部は、非同期コールバックになります。

基本的に、.NET の Invoke メソッドに相当するものが必要です。これは可能ですか?

4

1 に答える 1

32

Queue (現在は Python 3 のキュー) クラスを使用して、ダミー スレッドが関数を入力し、メイン スレッドが消費するキューを設定します。

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()

デモ:

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()

版画:

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

その後、永久にブロックします

于 2013-09-24T19:47:57.960 に答える