awesome-patterns/synchronization/semaphore/main.go

53 lines
1.2 KiB
Go
Raw Permalink Normal View History

2017-11-22 09:42:17 +03:00
package main
import (
"fmt"
"sync"
"time"
)
func main() {
// a blocking channel to keep concurrency under control
semaphoreChan := make(chan struct{}, 10)
defer close(semaphoreChan)
// a wait group enables the main process a wait for goroutines to finish
wg := sync.WaitGroup{}
// a simple loop from 1 to 10
for i := 1; i <= 100; i++ {
// increment the wait group internal counter
wg.Add(1)
// print what we're about to be doing (will keep the order)
fmt.Printf("About to run #%d in a goroutine\n", i)
// fire off a goroutine with the index in a closure since it will be modified
go func(i int) {
// block until the semaphore channel has room
// this could also be moved out of the goroutine
// which would make sense if the list is huge
semaphoreChan <- struct{}{}
// pretend to do some synchronous work
time.Sleep(time.Second)
// tell the wait group that we be done
wg.Done()
// print an message containing the index (won't keep order)
fmt.Printf("About to exit #%d from a goroutine\n", i)
// clear a spot in the semaphore channel
<-semaphoreChan
}(i)
}
// wait for all the goroutines to be done
wg.Wait()
}