9

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

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. 如何实现使用装饰器停止长线程的方法?

4

3 回答 3

9

如果您将功能扩展到

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,获取运行原始方法的线程,对它做任何你想做的事情(例如加入它),然后才调用下一个方法。

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

于 2013-10-21T13:20:42.313 回答
3
  1. 如果你想同步两个线程,你只需要在装饰函数中添加锁,而不是装饰器本身。

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

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

于 2013-10-21T13:16:42.133 回答
1

也许信号量可以帮助装饰器,像这样 - 计算从 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)
于 2017-08-06T01:27:27.783 回答