# `semaphore` – Semaphore classes

class eventlet.semaphore.Semaphore(value=1)

  An unbounded semaphore. Optionally initialize with a resource count, then `acquire()` and `release()` resources as needed. Attempting to `acquire()` when count is zero suspends the calling greenthread until count becomes nonzero again.

  This is API-compatible with `threading.Semaphore`.

  It is a context manager, and thus can be used in a with block:

      sem = Semaphore(2)
      with sem:
        do_some_stuff()

  If not specified, value defaults to 1.

  It is possible to limit acquire time:

      sem = Semaphore()
      ok = sem.acquire(timeout=0.1)
      # True if acquired, False if timed out.

  acquire(blocking=True, timeout=None)

    Acquire a semaphore.

    When invoked without arguments: if the internal counter is larger than zero on entry, decrement it by one and return immediately. If it is zero on entry, block, waiting until some other thread has called release() to make it larger than zero. This is done with proper interlocking so that if multiple acquire() calls are blocked, release() will wake exactly one of them up. The implementation may pick one at random, so the order in which blocked threads are awakened should not be relied on. There is no return value in this case.

    When invoked with blocking set to true, do the same thing as when called without arguments, and return true.

    When invoked with blocking set to false, do not block. If a call without an argument would block, return false immediately; otherwise, do the same thing as when called without arguments, and return true.

    Timeout value must be strictly positive.

  property balance

    An integer value that represents how many new calls to `acquire()` or `release()` would be needed to get the counter to 0. If it is positive, then its value is the number of acquires that can happen before the next acquire would block. If it is negative, it is the negative of the number of releases that would be required in order to make the counter 0 again (one more release would push the counter to 1 and unblock acquirers). It takes into account how many greenthreads are currently blocking in `acquire()`.

  bounded()

    Returns False; for consistency with `CappedSemaphore`.

  locked()

    Returns true if a call to acquire would block.

  release(blocking=True)

    Release a semaphore, incrementing the internal counter by one. When it was zero on entry and another thread is waiting for it to become larger than zero again, wake up that thread.

    The blocking argument is for consistency with CappedSemaphore and is ignored

class eventlet.semaphore.BoundedSemaphore(value=1)

  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.

  release(blocking=True)

    Release a semaphore, incrementing the internal counter by one. If the counter would exceed the initial value, raises ValueError. When it was zero on entry and another thread is waiting for it to become larger than zero again, wake up that thread.

    The blocking argument is for consistency with `CappedSemaphore` and is ignored

class eventlet.semaphore.CappedSemaphore(count, limit)

  A blockingly bounded semaphore.

  Optionally initialize with a resource count, then `acquire()` and `release()` resources as needed. Attempting to `acquire()` when count is zero suspends the calling greenthread until count becomes nonzero again. Attempting to `release()` after count has reached limit suspends the calling greenthread until count becomes less than limit again.

  This has the same API as `threading.Semaphore`, though its semantics and behavior differ subtly due to the upper limit on calls to `release()`. It is not compatible with `threading.BoundedSemaphore` because it blocks when reaching limit instead of raising a ValueError.

  It is a context manager, and thus can be used in a with block:

      sem = CappedSemaphore(2)
      with sem:
        do_some_stuff()

  acquire(blocking=True)

    Acquire a semaphore.

    When invoked without arguments: if the internal counter is larger than zero on entry, decrement it by one and return immediately. If it is zero on entry, block, waiting until some other thread has called release() to make it larger than zero. This is done with proper interlocking so that if multiple acquire() calls are blocked, release() will wake exactly one of them up. The implementation may pick one at random, so the order in which blocked threads are awakened should not be relied on. There is no return value in this case.

    When invoked with blocking set to true, do the same thing as when called without arguments, and return true.

    When invoked with blocking set to false, do not block. If a call without an argument would block, return false immediately; otherwise, do the same thing as when called without arguments, and return true.

  property balance

    An integer value that represents how many new calls to `acquire()` or `release()` would be needed to get the counter to 0. If it is positive, then its value is the number of acquires that can happen before the next acquire would block. If it is negative, it is the negative of the number of releases that would be required in order to make the counter 0 again (one more release would push the counter to 1 and unblock acquirers). It takes into account how many greenthreads are currently blocking in `acquire()` and `release()`.

  bounded()

    Returns true if a call to release would block.

  locked()

    Returns true if a call to acquire would block.

  release(blocking=True)

    Release a semaphore. In this class, this behaves very much like an `acquire()` but in the opposite direction.

    Imagine the docs of `acquire()` here, but with every direction reversed. When calling this method, it will block if the internal counter is greater than or equal to limit.