from https://www.cnblogs.com/tr3e/p/7995689.html
1,占位
func HeavyWork(id int) { rand.Seed(int64(id)) interval := time.Duration(rand.Intn(3)+1) * time.Second time.Sleep(interval) fmt.Printf("HeavyWork %-3d cost %v\n", id, interval) }
2,每个任务完成后向waitChan写入一个数据,在收到N个完成信号后退出
// "talk is cheap, show me the code." func main() { waitChan := make(chan int, 1) for i := 0; i < N; i++ { go func(n int) { HeavyWork(n) waitChan <- 1 }(i) } cnt := 0 for range waitChan { //是用for 读取chan,如果不读取, go func 会阻塞, 主程序for 结束时,也就是并发结束时 cnt++ if cnt == N { break } } close(waitChan) fmt.Println("finished") }
和这一段等效
// "talk is cheap, show me the code."
// Add 用来添加 goroutine 的个数。Done 执行一次数量减 1。Wait 用来等待结束 func main() { wg := sync.WaitGroup{} for i := 0; i < N; i++ { wg.Add(1) go func(n int) { defer wg.Done() HeavyWork(n) }(i) } wg.Wait() fmt.Println("finished") }
##########################################
超时机制
1, 超时
func main() { ok, quit := make(chan int, 1), make(chan int, 1) go func() { i := 0 for { select { case <- quit: //如果quit成功读到数据,则进行该case处理语句,如果不给 quit 传值,则不执行 ok <- 1 //给chan ok 传值,如果没有读ok,则阻塞 return default: HeavyWork(i) i++ } } }() time.Sleep(5 * time.Second) quit <- 1 //不给quit值,会 <-ok }
原文:https://www.cnblogs.com/eiguleo/p/12968460.html