多线程程序最令人头疼的是各种锁,写起来麻烦也容易出错。
还好python中有装饰器这种方便的神器存在,只需像单线程一样写程序,然后,在外边包上同步锁装饰器就可以了。
例如:
复制代码 代码示例:
import threading
def sync(lock):
def syncWithLock(fn):
def newFn(*args,**kwargs):
lock.acquire()
try:
return fn(*args,**kwargs)
finally:
lock.release()
newFn.func_name = fn.func_name
newFn.__doc__ = fn.__doc__
return newFn
return syncWithLock
lock = threading.Lock()
@sync(lock)
def fn():
global x
for i in range(10):
x+=1
if __name__ == "__main__":
x = 0
th = threading.Thread(target=fn)
th2 = threading.Thread(target=fn)
th3 = threading.Thread(target=fn)
th.start()
th2.start()
th3.start()
th.join()
th2.join()
th3.join()
print x#30
如此,便可以派出多个线程来执行fn方法,而不用担心出现数据出错。
然而,有时需要对实例方法加锁,一般来说该如何写呢?
复制代码 代码示例:
class Test(object):
def __init__(self):
self.lock = threading.Lock()
@sync(self.lock)
def fn(self):
pass
然而很遗憾,@sync(self.lock)里的self并无所指,而又无法得到实例对象本身的引用。
然而python的动态语言特性又可以通过一些特别的方法来实现目的,目前我是这么做的:
复制代码 代码示例:
class Test(object):
def __init__(self):
self.lock = threading.Lock()
self.__decFns()
def __decFns(self):
@sync(self.lock)
def __fn():
pass
self.fn = __fn
编写了一个帮助函数__decFns,用来帮助间接实现对实例方法的加锁,在__decFns里可以获取实例的引用self进行加锁,然后把相应的方法绑定到方法接口供外部使用。
各位有更好的办法,欢迎分享。