转载自:http://blog.donews.com/limodou/archive/2004/12/20/208356.aspx
qiangning hong在我的blog说可以考虑使用decorator来实现线程同步,我想是可以的,下面是我写得测试代码,大家可以试一试:
Code
import threading
import time
lock = threading.Lock()
def addlock(func):
def new_run(self):
lock.acquire()
ret = func(self)
lock.release()
return ret
return new_run
class NewThread(threading.Thread):
num = 0
def run(self):
while 1:
if not self.count_num():
break
@addlock
def count_num(self):
print 'begin', self.getName(), NewThread.num
if NewThread.num < 10:
time.sleep(0.01)
NewThread.num += 1
print 'end', self.getName(), NewThread.num
time.sleep(0.01)
return True
else:
return False
threads = []
for i in range(3):
t = NewThread()
t.start()
threads.append(t)
for thread in threads:
thread.join()
这是有线程同步的版本,大家把@addlock注释掉就是非线程同步的了。使用decorator需要使用2.4版本的python来执行。
线程同步我简单的使用了锁。addlock是一个decorator函数,它对原处理函数的前后加入了获得锁和释放锁的处理。
NewThread是一个自定义线程类,count_num是用来进行计数的。
整个程序是对线程类的类变量num进行计数。想法就是先得到num的值,然后延迟,再对num加1。由于是多线程,如果不使用线程同步机制会造成当一个线程看到一个值时,由于时间的延迟,在对num加1时,有可能不再是原来的值了。而使用线程同步可以避免这样的问题。使用decorator的好处是,代码相对独立。象演示同步与非同步只要加上@addlock即可。代码也显得很简洁。特别是对于不想修改原来的函数,但又想加入一些其它的控制时,使用decorator非常方便。
执行结果:
非线程同步:
begin Thread-1 0
begin Thread-2 0
begin Thread-3 0
end Thread-1 1
end Thread-2 2
end Thread-3 3
begin Thread-1 3
begin Thread-2 3
begin Thread-3 3
end Thread-1 4
end Thread-2 5
end Thread-3 6
begin Thread-1 6
begin Thread-2 6
begin Thread-3 6
end Thread-1 7
end Thread-2 8
end Thread-3 9
begin Thread-1 9
begin Thread-2 9
begin Thread-3 9
end Thread-1 10
end Thread-2 11
end Thread-3 12
begin Thread-1 12
begin Thread-2 12
begin Thread-3 12
线程同步:
begin Thread-1 0
end Thread-1 1
begin Thread-2 1
end Thread-2 2
begin Thread-3 2
end Thread-3 3
begin Thread-1 3
end Thread-1 4
begin Thread-2 4
end Thread-2 5
begin Thread-3 5
end Thread-3 6
begin Thread-1 6
end Thread-1 7
begin Thread-2 7
end Thread-2 8
begin Thread-3 8
end Thread-3 9
begin Thread-1 9
end Thread-1 10
begin Thread-2 10
begin Thread-3 10
begin Thread-1 10
关于decorator比较详细的内容可以参考我写的Blog 《 [Python学习]decorator的使用 》