Back to questions
Middle
3
type Sem interface { Lock() error //возвращает ошибку если полный канал TryLock() bool // мы просто рытаемся залочить если получилось то true Release() //освобождение канала Cap() int // кол раб горутин FreeSpace() int //показывает сколько свободного места в канале } //структура //channel - подумать на буфером //capacity int //mutex
Companies where asked
FinFrame
Answer from AI
sobes.tech AI
Интерфейс Sem описывает семафор с возможностью блокировки и освобождения ресурсов, а также получения информации о состоянии.
Для реализации можно использовать буферизированный канал (channel) в Go, где размер буфера соответствует capacity — максимальному количеству одновременно работающих горутин.
- Lock() error — пытается занять слот, если канал заполнен (все слоты заняты), возвращает ошибку.
- TryLock() bool — пытается занять слот без блокировки, возвращает true если получилось.
- Release() — освобождает слот, освобождая место в канале.
- Cap() int — возвращает ёмкость канала (максимальное число слотов).
- FreeSpace() int — возвращает количество свободных слотов (свободное место в канале).
Пример реализации:
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)
}
}
Таким образом, канал служит счётчиком занятых слотов, а буфер — максимальным количеством одновременно работающих горутин. Мьютекс в данном случае не нужен, так как операции с каналом потокобезопасны.