def BoundedSemaphore(*args, **kwargs):
"""A factory function that returns a new bounded semaphore.
A bounded semaphore checks to make sure its current value doesn't exceed its
initial value. If it does, ValueError is raised. In most situations
semaphores are used to guard resources with limited capacity.
If the semaphore is released too many times it's a sign of a bug. If not
given, value defaults to 1.
Like regular semaphores, bounded semaphores manage a counter representing
the number of release() calls minus the number of acquire() calls, plus an
initial value. The acquire() method blocks if necessary until it can return
without making the counter negative. If not given, value defaults to 1.
"""
return _BoundedSemaphore(*args, **kwargs)
翻译:BoundedSemaphore是一个工厂函数,它返回一个新的BoundedSemaphore(有限制的信号量)对象。
一个有限制的信号量负责检查它的当前值没有超过它的初始值,一旦超过了,就会报ValueError异常。大部分情况下,信号量主要用来保护有限的资源。
如果一个信号量被release太多,这可能引起BUG。如果没有指定初始值,那么初始值为1。
和普通的信号量一样,有限的信号量内部维护一个计数器,该计数器=initialValue+release-acquire。当 计数器的值为0时,acquire方法调用会被阻塞。计数器初始值为1。
真正的有限制的信号量类_BoundedSemaphore:
class _BoundedSemaphore(_Semaphore): #继承普通信号量类_Semaphore
"""A bounded semaphore checks to make sure its current value doesn't exceed
its initial value. If it does, ValueError is raised. In most situations
semaphores are used to guard resources with limited capacity.
"""
def __init__(self, value=1, verbose=None):
_Semaphore.__init__(self, value, verbose) #调用父类构造函数
self._initial_value = value #新增属性,记录信号量初始值
def release(self):
"""Release a semaphore, incrementing the internal counter by one.
When the counter is zero on entry and another thread is waiting for it
to become larger than zero again, wake up that thread.
If the number of releases exceeds the number of acquires,
raise a ValueError.
"""
with self._Semaphore__cond:
if self._Semaphore__value >= self._initial_value: #当前值大于初始值,抛异常
raise ValueError("Semaphore released too many times")
self._Semaphore__value += 1
self._Semaphore__cond.notify()
**演示:**普通信号量可以无限制的释放
import threading
sm=threading.Semaphore(0) #初始值为0
print 'initial value =%d' % sm._Semaphore__value
for i in range(100): # 释放100次
sm.release()
print 'current value =%d' % sm._Semaphore__value
运行结果:
C:\Python27\python.exe E:/pythonproj/基础练习/t8.py
initial value =0
current value =100
Process finished with exit code 0
可以发现,普通信号量可以被无数次的释放。
**演示:**有限制的信号量,不可以被无数次释放,一次最多只能释放初始值大小,负责抛异常。
import threading
bsm=threading.BoundedSemaphore(5) #定义一个初始值为5的信号量
#通过下面的5次acquire,将信号量全部用掉
bsm.acquire()
bsm.acquire()
bsm.acquire()
bsm.acquire()
bsm.acquire()
for i in range(1,101):#尝试100次释放
bsm.release()
print 'release %d times' % i
运行结果:
C:\Python27\python.exe E:/pythonproj/基础练习/t8.py
release 1 times
release 2 times
release 3 times
release 4 times
release 5 times
Traceback (most recent call last):
File "E:/pythonproj/������ϰ/t8.py", line 12, in <module>
bsm.release()
File "C:\Python27\lib\threading.py", line 537, in release
raise ValueError("Semaphore released too many times")
ValueError: Semaphore released too many times
Process finished with exit code 1
从运行结果可以看出,该信号量一次最多能被释放5次,也就是初始值。