一、Lock 对象
1. 基本介绍
- Lock.acquire([blocking])
获取一把锁,阻塞的或者非阻塞的。
当调用时blocking参数设置为True(默认值),将阻塞直至锁变成unblocked,然后设置它的状态为locked并返回True。
当调用时blocking参数设置为False,将不会阻塞。
- Lock.release()
释放一把锁。
当锁是locked时,重置它为unlocked,然后返回。如果存在其他阻塞的线程正在等待锁变成unblocked状态,只会允许它们中的一个继续。
在一把没有锁住的锁上调用时,引发一个ThreadError 。
2. 简单Lock()例子
# coding: utf-8
import threading
count = 0
def fun(lcok):
# 全局变量
global count
# 获得加锁
lcok.acquire()
count += 1
# 释放锁
lcok.release()
if __name__ == '__main__':
# 声明一个锁
lcok = threading.Lock()
thread = threading.Thread(target=fun, args=(lcok,))
thread.start()
3. 多线程Lock()例子
这个例子中,在对全局变量操作时需要加锁,如果不加锁的话,最后count值有可能不是200000,因为两个线程同时执行(但是Python不是真正的多线程,具体原因介绍Python的GIL特性请参考网址:http://www.cnblogs.com/mindsbook/archive/2009/10/15/thread-safety-and-GIL.html),会遇到对同一变量的操作,这样就会出现错误。
# coding: utf-8
import threading
count = 0
def fun(lcok):
# 全局变量
global count
for i in xrange(100000):
# 获得加锁
lcok.acquire()
count += 1
# 释放锁
lcok.release()
if __name__ == '__main__':
# 声明一个锁
lcok = threading.Lock()
# 创建多个线程,一同执行
for i in xrange(2):
thread = threading.Thread(target=fun, args=(lcok,))
thread.start()
4. 其他方法操作Lock()例子
使用with来获得加锁,等同于acquire()和release()一同操作。
# coding: utf-8
import threading
count = 0
def fun(lcok):
# 全局变量
global count
# 获得加锁
with lcok:
count += 1
if __name__ == '__main__':
# 声明一个锁
lcok = threading.Lock()
thread = threading.Thread(target=fun, args=(lcok,))
thread.start()
二、RLock对象
1. 基本介绍
一个可重入所示一个同步原语,它可以被相同的线程获得多次。 当线程在获得加锁之后,又需要共享资源,需要再次加锁。这时就可以使用RLock。
注意,acquire()和release()要成对出现,否则会报错
2. 简单Lock()例子
# coding: utf-8
import threading
count = 0
def fun(lcok):
# 全局变量
global count
# 获得加锁
lcok.acquire()
# 再一次获得加锁
lcok.acquire()
count += 1
# 释放锁
lcok.release()
# 释放锁
lcok.release()
if __name__ == '__main__':
# 声明一个RLock锁
lcok = threading.RLock()
thread = threading.Thread(target=fun, args=(lcok,))
thread.start()