直接使用主线程阻塞等待所有协程都处理完毕后退出
package main import ( "fmt" "sync" ) func putNum(intChan chan int) { for i := 2; i < 10000; i++ { intChan <- i } close(intChan) } func calcPrime(intChan chan int, primeChan chan int, exitChan chan bool) { for num := range intChan { flag := true for i := 2; i < num; i++ { if num%i == 0 { flag = false break } } if flag { primeChan <- num } } exitChan <- true } func printPrime(primeChan chan int) { for prime := range primeChan { fmt.Println(prime) } } func main() { routineNum := 16 intChant := make(chan int, 1000) primeChan := make(chan int, 1000) exitChan := make(chan bool, routineNum) // 写协程 go putNum(intChant) // 计算协程 for i := 0; i < routineNum; i++ { go calcPrime(intChant, primeChan, exitChan) } // 打印协程 go printPrime(primeChan) // 处理退出,主线程阻塞直至所有协程都处理完毕 for i := 0; i < 16; i++ { <-exitChan } close(primeChan) fmt.Println("执行完毕") }
第二种利用waitGroup等待所有协程均完成
package main import ( "fmt" "sync" ) var wg sync.WaitGroup func putNum(intChan chan int) { for i := 2; i < 10000; i++ { intChan <- i } close(intChan) wg.Done() } func calcPrime(intChan chan int, primeChan chan int, exitChan chan bool) { for num := range intChan { flag := true for i := 2; i < num; i++ { if num%i == 0 { flag = false break } } if flag { primeChan <- num } } exitChan <- true wg.Done() } func printPrime(primeChan chan int) { for prime := range primeChan { fmt.Println(prime) } wg.Done() } func closeChan(exitChan chan bool, primeChan chan int) { for i := 0; i < 16; i++ { <-exitChan } close(primeChan) } func main() { routineNum := 16 intChant := make(chan int, 1000) primeChan := make(chan int, 1000) exitChan := make(chan bool, routineNum) // 写协程 wg.Add(1) go putNum(intChant) // 计算协程 for i := 0; i < routineNum; i++ { wg.Add(1) go calcPrime(intChant, primeChan, exitChan) } // 打印协程 wg.Add(1) go printPrime(primeChan) // 处理退出 go closeChan(exitChan, primeChan) wg.Wait() fmt.Println("执行完毕") }