Semaphores are a very general synchronization mechanism that can be used to implement mutexes, limit access to multiple resources, solve the readers-writers problem, etc. There is no semaphore implementation in Go's sync package, but they can be emulated easily using buffered channels:
We don't care about what is stored in the channel, only its length; therefore, we start by making a channel that has variable length but 0 size (in bytes): type empty {} type semaphore chan empty We then can initialize a semaphore with an integer value which encodes the number of available resources. If we have N resources, we'd initialize the semaphore as follows: sem = make(semaphore, N) Now our semaphore operations are straightforward: // acquire n resources e := empty{}
func (s semaphore) V(n int) { This can be used to implement a mutex, among other things: /* mutexes */ func (s semaphore) Lock() { s.P(1) } func (s semaphore) Unlock() { s.V(1) } /* signal-wait */ func (s semaphore) Signal() { s.V(1) } func (s semaphore) Wait(n int) { s.P(n) } |
Concurrency >