对python实例类运用同步锁装饰器

多线程程序最令人头疼的便是各种锁,写起来麻烦也容易出错。 还好Python中有装饰器这种方便的神器存在,我们只需像单线程一样写程序 ,然后在外边包上同步锁装饰器就ok了。比如:

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进行加锁,然后把相应的方法绑定到方法接口供外部使用。 虽然解决了问题,但是总觉的不太好看,读者若有更好思路欢迎讨论。

posted @ 2011-05-31 16:21  simayixin  阅读(2632)  评论(0编辑  收藏  举报