pythonic Thread サブクラスと組み合わせて単純な pythonic キューを使用しています...
class WorkerThread( threading.Thread ):
def __init__( self, *args, **kvargs ):
threading.Thread.__init__( self, *args, **kvargs )
self.input_queue = Queue()
def send( self, item ):
assert type( item ) is list
assert item # i.e. must have at least one element
# check that first item is callable
assert hasattr( item[ 0 ], "__call__" )
self.input_queue.put( item )
def close( self ):
self.input_queue.put( None )
self.input_queue.join()
def run( self ):
while True:
method_call_elements = self.input_queue.get()
if method_call_elements is None: # "poison pill"
break
method_args = method_call_elements[ 1 : ]
method_call_elements[ 0 ]( *method_args )
self.input_queue.task_done()
self.input_queue.task_done()
return
... したがって、送信するのはリストであり、その最初の項目はメソッドであり、オプションのその他の要素はメソッドに提供する任意のパラメーターです。NB は Java でこの種の楽しいことを行うことはできません!
問題は、呼び出されたメソッドから値を返す単純な pythonic メソッドがあるかどうかです。Java では明らかに、操作する Callable および Future インターフェースがあります。そして、そのようなJavaクラスをさらに使用すると、コードがどのように変更されるかがわかります...実際、いくつかの可能性があると思います。しかし、Python には「未来」タイプの状況に対処するための規定があるかどうか疑問に思っただけです。
ところで、私は Definitive Guide を見ました。
後で:
興味のある方は、これが私の Java 指向のソリューションです。
@property
def size( lmm_self ):
class FindNodeMapSizeTask( Callable ):
def call( self ):
genLog.info( "thread %s - inside FindNodeMapSizeTask.call()", Thread.currentThread().id )
return len( lmm_self.id_to_node_map )
size_result = FutureTask( FindNodeMapSizeTask() )
lmm_self.internal_ops_worker_thread.send([ size_result.run ])
genLog.info( "thread %s - waiting for Future.get()...", Thread.currentThread().id )
map_size = size_result.get()
genLog.info( "thread %s - ... got Future.get(): %s", Thread.currentThread().id, map_size)
return map_size
典型的な出力:
スレッド 20 - Future.get() を待っています...
スレッド 21 - FindNodeMapSizeTask.call() 内
スレッド 20 - ... 取得した Future.get(): 1121
ツリーサイズ: 1121
size_result.get() は、def send() で method_call_elements = self.input_queue.get() の後に sleep( 1 ) が配置されていても、len( ... ) が結果を配信するまで size( lmm_self ) からの戻りをブロックします。
問題なく動作しますが、もちろん Java FutureTask を使用します。これに対するpythonicの解決策は私にとって興味深いでしょう...
後でまだ
うーん... Beasley Python Essential Referenceを参照すると、これらの行に沿ってthreading.Eventを使用してsthgを実行するかなり明確な方法がわかります...