def Condition(*args, **kwargs):
return _Condition(*args, **kwargs)
class _Condition(_Verbose):
# 条件变量允许一个或多个线程进入到等待状态,直到它们被其他线程唤醒
"""Condition variables allow one or more threads to wait until they are
notified by another thread.
"""
def __init__(self, lock=None, verbose=None):
...
if lock is None:
lock = RLock()
# Condition的底层锁,默认是RLock
self.__lock = lock

# 将Condition的acquire()和release()方法设置为底层锁的acquire()和release()方法

self.acquire = lock.acquire

self.release = lock.release

try:

self._release_save = lock._release_save

except AttributeError:

pass

try:

self._acquire_restore = lock._acquire_restore

except AttributeError:

pass

try:

self._is_owned = lock._is_owned

except AttributeError:

pass

# waiting池
self.__waiters = []
def _is_owned(self):
# 如果当前线程持有锁,则返回True,否则返回False
# Condition也支持上下文管理。
# + 当进入到Condtion对象时,会获取底层锁
# + 当离开到Condtion对象时,会释放底层锁
def __enter__(self):
return self.__lock.__enter__()
def __exit__(self, *args):
return self.__lock.__exit__(*args)
# 对于RLock而言,调用release()方法,并不一定会真正的释放锁。
# + 因此,它提供了_release_save()方法,该方法会真正的释放锁,
# + + 并且将RLock内部维护的状态,返回给调用方。
# 之后,线程再次获取到底层锁之后,再将状态重置回去
# RLock内部会维护两个状态:owner-拥有锁的线程的id,count-该线程获取了多少次锁
# 只有底层锁没有_release_save()和_acquire_restore()方法时,才用下面的实现
def _release_save(self):
self.__lock.release() # No state to save
def _acquire_restore(self, x):
self.__lock.acquire() # Ignore saved state
def wait(self, timeout=None):
# 1,如果当前线程,没有获取到底层锁,那么抛出异常
if not self._is_owned():
raise RuntimeError("cannot wait on un-acquired lock")
# 2,创建一个锁对象,并获取它,然后把它放到waiting池
waiter = _allocate_lock()
waiter.acquire()
self.__waiters.append(waiter)
# 3,释放底层锁,并保存锁对象的内部状态
saved_state = self._release_save()
try: # restore state no matter what (e.g., KeyboardInterrupt)
if timeout is None:
# 3.1,如果timeout是None,那么再次以阻塞的方式获取锁对象
# + 因此当前线程已经获取了一次该锁,因此当前线程会阻塞,直到其他线程释放该锁
waiter.acquire()
if __debug__:
self._note("%s.wait(): got it", self)
else:
# 3.2,如果timeout不是None,那么重复下面的流程:
# + 1,以非阻塞方式获取锁
# + + 1.1,如果获取成功,说明其他线程释放了该锁,那么退出循环
# + + 1.2,如果获取失败,那么看是否达到了超时时间,如果达到了,那么退出循环;否则,继续
# + 2,sleep一小段时间,然后回到步骤1
# + + 每次循环sleep的时长,是从0.0005秒开始,指数增长,最多增长到0.05秒
# + + + 第一次是:0.0005,第二次是:0.001,...
endtime = _time() + timeout
delay = 0.0005 # 500 us -> initial delay of 1 ms
while True:
gotit = waiter.acquire(0)
if gotit:
break
remaining = endtime - _time()
if remaining <= 0:
break
delay = min(delay * 2, remaining, .05)
_sleep(delay)
if not gotit:
...
try:
# 3.3,如果因为超时,而不是被唤醒,退出的wait(),那么将锁从waiting池中移除
# + 因为当线程被唤醒的时候,调用notify的线程会将锁从waiting池中移除
self.__waiters.remove(waiter)
except ValueError:
pass
else:
...
finally:
# 4,获取底层锁,并重置锁对象的内部状态
self._acquire_restore(saved_state)
def notify(self, n=1):
# 1,如果当前线程,没有获取到底层锁,那么抛出异常
if not self._is_owned():
raise RuntimeError("cannot notify on un-acquired lock")
__waiters = self.__waiters
waiters = __waiters[:n]
if not waiters:
if __debug__:
self._note("%s.notify(): no waiters", self)
return
self._note("%s.notify(): notifying %d waiter%s", self, n,
n!=1 and "s" or "")
# 2,唤醒waiting池中前n个线程,并将他们从waiting池中移除
for waiter in waiters:
waiter.release()
try:
__waiters.remove(waiter)
except ValueError:
pass
def notifyAll(self):
self.notify(len(self.__waiters))
notify_all = notifyAll