Getting started
1) make buffered channel
sem := make(chan int, 10)
2) in synchronous process, send some variable to buffered channel (this step called acquire)
sem <- i
3) in asynchronous process, release variable from buffered channel (this step called release)
<- sem
Result from log
start process [9] start process [0] start process [7] start process [6] start process [3] start process [2] start process [4] start process [8] start process [1] start process [5] <- 10 processes start concurrency end process [0] 0.0001 seconds start process [10] <- process 10 start after process 0 end end process [2] 4.0014 seconds end process [1] 4.0012 seconds start process [12] start process [11] <- process 11, 12 start after process 1, 2 end end process [3] 5.0011 seconds start process [13] end process [4] 0.0001 seconds start process [14] end process [5] 6.0014 seconds start process [15] end process [6] 1.0011 seconds start process [16] end process [7] 8.0013 seconds start process [17] ...
Remark
Standard package
golang.org/x/sync/semaphore
Code
package main import ( "fmt" "math/rand" "time" ) const ( MAX_CONCURRENT = 10 // Allow max concurrent TOTAL_PROCESSES = 1000 // Total loop count MAX_RANDOM_SECONDS = 20 ) func main() { sem := make(chan int, MAX_CONCURRENT) for i := range TOTAL_PROCESSES { sem <- i // *** send i to buffered channel. If channel sem full, it blocked for loop. go func(i int) { start := time.Now() fmt.Printf("start\tprocess\t[%d]\n", i) defer func() { // <- sem will release a value, so sem channel will available for next value fmt.Printf("end\tprocess\t[%d]\t %.4f seconds\n", <-sem, time.Since(start).Seconds()) }() iv := rand.Intn(MAX_RANDOM_SECONDS) * int(time.Second) time.Sleep(time.Duration(iv)) }(i) } }
Top comments (0)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.