Middle
Define the Sem interface and its methods.
sobes.tech AI
Answer from AI
The Sem interface describes a semaphore with the ability to lock and release resources, as well as to obtain status information.
For implementation, a buffered channel in Go can be used, where the buffer size corresponds to the capacity — the maximum number of goroutines that can operate simultaneously.
- Lock() error — attempts to acquire a slot; if the channel is full (all slots are occupied), it returns an error.
- TryLock() bool — attempts to acquire a slot without blocking; returns true if successful.
- Release() — releases a slot, freeing space in the channel.
- Cap() int — returns the capacity of the channel (maximum number of slots).
- FreeSpace() int — returns the number of free slots (available space in the channel).
Example implementation:
Type Sem interface {
Lock() error
TryLock() bool
Release()
Cap() int
FreeSpace() int
}
Type semaphore struct {
ch chan struct{}
}
func NewSemaphore(capacity int) Sem {
return &semaphore{ch: make(chan struct{}, capacity)}
}
func (s *semaphore) Lock() error {
select {
case s.ch <- struct{}{}:
return nil
default:
return errors.New("semaphore is full")
}
}
func (s *semaphore) TryLock() bool {
select {
case s.ch <- struct{}{}:
return true
default:
return false
}
}
func (s *semaphore) Release() {
select {
case <-s.ch:
default:
panic("release called on empty semaphore")
}
}
func (s *semaphore) Cap() int {
return cap(s.ch)
}
func (s *semaphore) FreeSpace() int {
return cap(s.ch) - len(s.ch)
}
Thus, the channel acts as a counter for occupied slots, and the buffer as the maximum number of goroutines that can run simultaneously. Mutex is not needed here, as channel operations are thread-safe.