直接使用主线程阻塞等待所有协程都处理完毕后退出
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("执行完毕")
}