python threading模块、BoundedSemaphore类讲解

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次,也就是初始值。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

历史五千年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值