var ErrNoTickets = errors.New("semaWait deadline exceeded!")// nonbinary/counting semaphores// used in reader-writer locks where we have multiple readers and a single writer.type Semaphore struct { sem chan struct{ id int } timeout time.Duration // how long to wait to acquire the semaphore before giving up}// push to the chan on acquire denoting we are utilising the available resourcefunc (s *Semaphore) semaAcquire(id int) error { timer := time.NewTimer(s.timeout) select { case s.sem <- struct{ id int }{id: id}: timer.Stop() return nil case <-timer.C: fmt.Println("deadline exceeded in acquiring the semaphore!") return ErrNoTickets }}// just consume from the channelfunc (s *Semaphore) semaRelease() { ID := <-s.sem fmt.Printf("releasing the lock held by :%d\n", ID.id)}func (s *Semaphore) IsEmpty() bool { return len(s.sem) == 0}func semaInit(count int, timeout time.Duration) *Semaphore { sema := &Semaphore{ sem: make(chan struct{ id int }, count), timeout: timeout, } return sema}