2013-01-09 99 views
5

我想實現線程(使用裝飾)到我的應用程序,但無法理解有關鎖和管理線程的一些事情。線程與裝飾

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. 據我瞭解,方法1和method2不同步,但鎖的幫助下實現的那些東西同步。我如何將鎖添加到我的裝飾器函數中?

  2. 如何實現使用裝飾器來停止長線程的方法?

+0

它是什麼你想要在兩個線程之間進行同步? – awatts

+0

可能是我說的東西不正確。 我想在某些情況下(並非總是)在1個線程之後運行第二個線程,而不是並行運行。 –

+0

當然,最簡單的方法就是不要在這種情況下在線程中運行代碼。在這種情況下,您可以使用兩種類似的方法,一種在線程中執行任務,另一種執行任務。或者在調用時傳入參數,以指示是否要調用該線程。 – awatts

回答

4

使用

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 

允許您在線程更好的控制:你可以做那麼

c = A() 
t1 = c.method1() 
t1.join() # wait for it to finish 
t2 = c.method2() 
# ... 
3
  1. 如果你想兩個線程,你只需要添加的裝飾功能,而不是裝飾自己的內部鎖同步。

  2. 沒有簡單的方法來直接停止一個線程,唯一的方法是使用一個事件來發出它必須退出的線程的信號。

對於線程裝飾器,你可以看看pebble

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