带装饰器的线程

时间:2013-01-09 11:48:06

标签: python multithreading decorator

我正在尝试向我的应用程序实现线程(使用装饰器),但无法理解有关锁和管理线程的一些事情。

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. 据我所知,method1和method2不是同步的,而是在锁的帮助下同步实现的东西。如何为我的装饰器功能添加锁?

  2. 如何实现使用装饰器停止长线程的方法?

3 个答案:

答案 0 :(得分:6)

如果将功能扩展到

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

我。 e,获取原始方法运行的线程,用它做任何你想做的事情(例如加入它),然后再调用下一个方法。

如果您在特定情况下不需要它,您可以省略它。

答案 1 :(得分:3)

  1. 如果要同步两个线程,只需在装饰函数内添加锁,而不是装饰器本身。

  2. 没有一种直接停止线程的简单方法,唯一的方法就是使用一个事件来表示它必须退出的线程。

  3. 对于线程装饰器,您可以查看pebble

答案 2 :(得分:0)

也许Semaphores可以帮助装饰器,类似这样 - 计算从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)