1.单线程异步初始化待计算数据 intChannel
2.多线程并发计算素数并写入 primeChannel
3.单线程异步等待计算结束并关闭 exitChannel
package main
import (
"fmt"
//"runtime"
"time"
)
func putNum(intChannel chan int) {
for i := 0; i < 10000; i++ {
// 初始化数据放入管道
intChannel <- i
}
close(intChannel)
}
func primeNum(intChannel chan int, primeChannel chan int, exitChannel chan bool) {
for {
// 从管道中取数据进行计算
num, ok := <-intChannel
if !ok {
// 管道为空
break
}
flag := true
for i := 2; i < num; i++ {
if num%i == 0 {
flag = false
continue
}
}
if flag {
// 素数放入管道
primeChannel <- num
}
}
exitChannel <- true
}
func main() {
//numCPU := runtime.NumCPU()
numCPU := 16
fmt.Println("CPU数量:", numCPU)
intChannel := make(chan int, 10000)
primeChannel := make(chan int, 2000)
exitChannel := make(chan bool, numCPU)
start := time.Now().UnixMilli()
// 单线程初始化管道
go putNum(intChannel)
// 多线程从intChannel中取数据进行计算
for i := 0; i < numCPU; i++ {
go primeNum(intChannel, primeChannel, exitChannel)
}
// 异步线程从exitChannel取数据,取完了则说明素数的计算结束了
go func() {
for i := 0; i < numCPU; i++ {
<-exitChannel
}
close(primeChannel)
}()
// 单线程从计算结果中取数据进行打印
for {
result, ok := <-primeChannel
if !ok {
break
}
fmt.Println("素数:", result)
}
fmt.Println("主线程结束")
end := time.Now().UnixMilli()
fmt.Println("计算结束,耗时:", end-start, "ms")
}