Semaphore
A counting semaphore for limiting concurrent access to a resource pool.
A semaphore manages a fixed number of permits. acquire blocks until
a permit is available; release returns one. Use critical: to
automatically acquire before and release after evaluating a block.
Semaphore new creates a binary semaphore (1 permit).
Semaphore new: n creates a semaphore with n permits.
Semaphore new capacity "=> 1"
(Semaphore new: 3) capacity "=> 3"
(Semaphore new: 3) available "=> 3"
Semaphore new hasAvailablePermits "=> true"
(Semaphore new: 2) isFull "=> false"
| s <Semaphore> |
s := Semaphore new: 3.
s tryAcquire.
s available "=> 2"
s := Semaphore new.
s tryAcquire "=> true"
s := Semaphore new.
s tryAcquire.
s tryAcquire "=> false"
s := Semaphore new.
s tryAcquire.
s isFull "=> true"
s := Semaphore new: 2.
s critical: [42] "=> 42"
"Rate-limiting concurrent work to 3 at a time"
| sem <Semaphore> wg <WaitGroup> |
sem := Semaphore new: 3.
wg := WaitGroup new.
1 to: 10 do: [:i |
wg wrap: [sem critical: [Process sleep: 100]]
].
wg wait
Class Methods
primitives
uncategorized
Create a binary semaphore with a single permit.
Semaphore new capacity "=> 1"
Semaphore new available "=> 1"
Create a semaphore with the given number of permits.
(Semaphore new: 5) capacity "=> 5"
(Semaphore new: 5) available "=> 5"
Instance Methods
primitives
uncategorized
Acquire a permit, blocking if none are available. Use
tryAcquire for a non-blocking alternative.
| sem <Semaphore> |
sem := Semaphore new: 2.
sem acquire.
sem release
Return the number of currently available permits.
(Semaphore new: 3) available "=> 3"
| s <Semaphore> |
s := Semaphore new: 3.
s tryAcquire.
s tryAcquire.
s available "=> 1"
Return the total permit capacity of the semaphore.
Semaphore new capacity "=> 1"
(Semaphore new: 10) capacity "=> 10"
Evaluate aBlock while holding a permit. The permit is
automatically released when the block finishes, even if an
error occurs.
(Semaphore new: 2) critical: [42] "=> 42"
| s <Semaphore> |
s := Semaphore new: 1.
s critical: ['done'].
s available "=> 1"
Return true if the semaphore has at least one available permit.
Semaphore new hasAvailablePermits "=> true"
| s <Semaphore> |
s := Semaphore new.
s tryAcquire.
s hasAvailablePermits "=> false"
Execute aBlock only if a permit is immediately available.
Returns the block's result if executed, or nil if no permit
was available.
Semaphore new ifAvailable: [42] "=> 42"
| s <Semaphore> |
s := Semaphore new.
s tryAcquire.
s ifAvailable: [42] "=> nil"
Return true if all permits are currently in use.
(Semaphore new: 2) isFull "=> false"
| s <Semaphore> |
s := Semaphore new.
s tryAcquire.
s isFull "=> true"
Return a string describing the semaphore and its permit state.
Semaphore new printString
"=> 'a Semaphore (1/1 available)'"
(Semaphore new: 3) printString
"=> 'a Semaphore (3/3 available)'"
Release a permit back to the semaphore, potentially unblocking a waiting process.
| s <Semaphore> |
s := Semaphore new: 1.
s tryAcquire.
s available "=> 0"
s release.
s available "=> 1"
Try to acquire a permit without blocking. Returns true if a
permit was acquired, false if none were available.
Semaphore new tryAcquire "=> true"
| s <Semaphore> |
s := Semaphore new.
s tryAcquire.
s tryAcquire "=> false"
Alias for critical:. Evaluate aBlock while holding a permit.
Semaphore new withPermit: [42] "=> 42"