/ ========================================================================== // $Id: semaphore.go,v 1.1 2020/01/28 23:16:28 jlang Exp $ // CSI2120 GO: Concurrency - semaphores and waitgroup // ========================================================================== // (C)opyright: // // Jochen Lang // EECS, University of Ottawa // 800 King Edward Ave. // Ottawa, On., K1N 6N5 // Canada. // http://www.eecs.uottawa.ca // // Creator: Jochen Lang // Email: jlang@eecs.uottawa.ca // ========================================================================== // $Log: semaphore.go,v $ // Revision 1.1 2020/01/28 23:16:28 jlang // Added semaphore and waitgroup example. // // ========================================================================== package main import ( "fmt" "math/rand" "sync" "time" ) // Channel with buffer size 10 var sem = make(chan int, 10) var wg sync.WaitGroup type Request struct { Num int } func NewRequest(i int) *Request { var r Request r.Num = i return &r } func handle(r *Request) { process(r) // Process the request <-sem // Done, room for next request. return } func process(r *Request) { defer wg.Done() ms := rand.Intn(1000) time.Sleep(time.Duration(ms) * time.Millisecond) fmt.Printf("Done %d \n", r.Num) return } func MyServer(queue chan *Request) { for { req := <-queue // receive a new request sem <- 1 // Are we below 10, if not wait go handle(req) } return } func main() { rand.Seed(42) queue := make(chan *Request) go MyServer(queue) for i := 0; i < 50; i++ { wg.Add(1) go func(j int) { queue <- NewRequest(j) }(i) } wg.Wait() }