MCPcopy
hub / github.com/python-trio/trio / Semaphore

Class Semaphore

src/trio/_sync.py:441–558  ·  view source on GitHub ↗

A `semaphore `__. A semaphore holds an integer value, which can be incremented by calling :meth:`release` and decremented by calling :meth:`acquire` – but the value is never allowed to drop below zero. If the value is zero, then

Source from the content-addressed store, hash-verified

439
440@final
441class Semaphore(AsyncContextManagerMixin):
442 """A `semaphore <https://en.wikipedia.org/wiki/Semaphore_(programming)>`__.
443
444 A semaphore holds an integer value, which can be incremented by
445 calling :meth:`release` and decremented by calling :meth:`acquire` – but
446 the value is never allowed to drop below zero. If the value is zero, then
447 :meth:`acquire` will block until someone calls :meth:`release`.
448
449 If you&#x27;re looking for a :class:`Semaphore` to limit the number of tasks
450 that can access some resource simultaneously, then consider using a
451 :class:`CapacityLimiter` instead.
452
453 This object&#x27;s interface is similar to, but different from, that of
454 :class:`threading.Semaphore`.
455
456 A :class:`Semaphore` object can be used as an async context manager; it
457 blocks on entry but not on exit.
458
459 Args:
460 initial_value (int): A non-negative integer giving semaphore&#x27;s initial
461 value.
462 max_value (int or None): If given, makes this a "bounded" semaphore that
463 raises an error if the value is about to exceed the given
464 ``max_value``.
465
466 """
467
468 def __init__(self, initial_value: int, *, max_value: int | None = None) -> None:
469 if not isinstance(initial_value, int):
470 raise TypeError("initial_value must be an int")
471 if initial_value < 0:
472 raise ValueError("initial value must be >= 0")
473 if max_value is not None:
474 if not isinstance(max_value, int):
475 raise TypeError("max_value must be None or an int")
476 if max_value < initial_value:
477 raise ValueError("max_values must be >= initial_value")
478
479 # Invariants:
480 # bool(self._lot) implies self._value == 0
481 # (or equivalently: self._value > 0 implies not self._lot)
482 self._lot = trio.lowlevel.ParkingLot()
483 self._value = initial_value
484 self._max_value = max_value
485
486 def __repr__(self) -> str:
487 if self._max_value is None:
488 max_value_str = ""
489 else:
490 max_value_str = f", max_value={self._max_value}"
491 return f"<trio.Semaphore({self._value}{max_value_str}) at {id(self):#x}>"
492
493 @property
494 def value(self) -> int:
495 """The current value of the semaphore."""
496 return self._value
497
498 @property

Callers 4

test_SemaphoreFunction · 0.85
test_Semaphore_boundedFunction · 0.85
test_ConditionFunction · 0.85
test_sync.pyFile · 0.85

Calls

no outgoing calls

Tested by 3

test_SemaphoreFunction · 0.68
test_Semaphore_boundedFunction · 0.68
test_ConditionFunction · 0.68

Used in the wild real call sites across dependent graphs

searching dependent graphs…