2013-01-09 8 views
5

私はアプリケーションにデコレータを使ってスレッドを実装しようとしていますが、ロックやスレッドの管理については理解できません。 デコレータ付きスレッド

  1. 私が理解したよう

    import threading 
    
    def run_in_thread(fn): 
        def run(*k, **kw): 
         t = threading.Thread(target=fn, args=k, kwargs=kw) 
         t.start() 
        return run 
    
    class A: 
        @run_in_thread 
        def method1(self): 
         for x in range(10000): 
          print x 
    
    
        @run_in_thread 
        def method2(self): 
         for y in list('wlkefjwfejwiefwhfwfkjshkjadgfjhkewgfjwjefjwe'): 
          print y 
    
        def stop_thread(self): 
         pass 
    
    c = A() 
    c.method1() 
    c.method2() 
    

    は、法1と方法2が同期されていないが、その原料の同期は、ロックの助けを借りて実現しています。デコレータ機能にロックを追加する方法は?

  2. デコレータを使用して長いスレッドを停止する方法をどうすれば実現できますか?

+0

2つのスレッド間で何を同期しますか? – awatts

+0

私は何かが間違っているかもしれません。 場合によっては(常にではありませんが)1つのスレッドの後に2つ目のスレッドを並列に実行する可能性があります。 –

+0

これを行う簡単な方法は、その場合にスレッド内でコードを実行しないことです。どちらの場合も、2つの同様のメソッドを持つことができます.1つはスレッド内でタスクを行い、もう1つはスレッドでは行いません。あるいは、呼び出しがスレッド化されるかどうかを示す呼び出し時にパラメータを渡します。 – awatts

答えて

4

あなたがスレッドをより細かく制御することができます:あなたは、

c = A() 
t1 = c.method1() 
t1.join() # wait for it to finish 
t2 = c.method2() 
# ... 
3
  1. あなたはシンプルな内装の機能ではなく、デコレーター自身の内側のロックを追加する必要がある2つのスレッドを同期したい場合。

  2. スレッドを直接停止する簡単な方法はありませんが、終了する必要があるスレッドに通知するためにイベントを使用する方法があります。

スレッドデコレータの場合は、pebbleをご覧ください。

def run_in_thread(fn): 
    def run(*k, **kw): 
     t = threading.Thread(target=fn, args=k, kwargs=kw) 
     t.start() 
     return t # <-- this is new! 
    return run 

を使用して

+0

とても面白いですね。 – glglgl

0

を行うことができますたぶんセマフォがデコレータに役立つ可能性があり、このような何か - 1〜1000階乗の数字を計算します:

import threading 

from functools import wraps 
from math import factorial 


DIC = {} 

def limit(number): 
    ''' This decorator limits the number of simultaneous Threads 
    ''' 
    sem = threading.Semaphore(number) 
    def wrapper(func): 
     @wraps(func) 
     def wrapped(*args): 
      with sem: 
       return func(*args) 
     return wrapped 
    return wrapper 

def async(f): 
    ''' This decorator executes a function in a Thread''' 
    @wraps(f) 
    def wrapper(*args, **kwargs): 
     thr = threading.Thread(target=f, args=args, kwargs=kwargs) 
     thr.start() 
    return wrapper 

@limit(10)  # Always use @limit as the outter decorator 
@async 
def calcula_fatorial(number): 
    DIC.update({number: factorial(number)}) 

@limit(10) 
def main(lista): 
    for elem in lista: 
     calcula_fatorial(elem) 


if __name__ == '__main__': 
    from pprint import pprint 
    main(range(1000)) 
    pprint(DIC) 
関連する問題