guv.semaphore
- greenthread-compatible semaphore¶guv.semaphore.
BoundedSemaphore
(value=1)[source]¶Bases: guv.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. 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) → None[source]¶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
guv.semaphore.
CappedSemaphore
(count, limit)[source]¶Bases: object
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()
balance
¶@property
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()
.
acquire
(blocking=True) → None[source]¶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.
release
(blocking=True) → None[source]¶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.
guv.semaphore.
Semaphore
(value=1)[source]¶Bases: object
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.
balance
¶@property
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()
.
acquire
(blocking=True, timeout=None) → None[source]¶Acquire a semaphore
This function behaves like threading.Lock.acquire()
.
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.
bounded
() → None[source]¶Returns False; for consistency with
CappedSemaphore
.