package main
import (
"fmt"
)
func putNum(intChan chan int) {
for i := 1; i <= 80; i++ {
intChan <- i
}
//关闭intChan
close(intChan)
}
//从intChan取出数据,并判断是否为素数,如果是,就放入到primeChan中
func primeNum(intChan chan int, primeChan chan int, exitChan chan bool) {
//使用for循环
var flag bool
for {
num, ok := <-intChan
//判断num是不是素数
if !ok { //如果取不到了也要退出循环
break
}
flag = true
for i := 2; i < num; i++ {
if num%i == 0 {
//说明该num不是素数
flag = false
break
}
}
if flag {
//将这个数就放到primeChan中去
primeChan <- num
}
}
fmt.Println("有一个primeNum协程取不到数据退出去了")
//这里还不能关闭primeChan这个管道
//向退出的管道写入true
exitChan <- true
}
func main() {
intChan := make(chan int, 1000) //intChan 是存放数据的管道
primeChan := make(chan int, 2000) //prime是存放素数的管道
exitChan := make(chan bool, 4)
go putNum(intChan) //这个协程开始 工作了
//开启4个协程,从intChan取出数据,并判断是否为素数,如果是的话就put
for i := 0; i < 4; i++ {
go primeNum(intChan, primeChan, exitChan)
}
//这里我们的主线程,要进行处理
//直接
go func() {
for i := 0; i < 4; i++ {
<-exitChan
}
//当从exitChan中取出了 4个结果就可以放心的关闭了
close(primeChan)
}()
for {
res, ok := <-primeChan
if !ok {
break
}
//否则就将结果打印
fmt.Printf("素数=%d\n", res)
}
fmt.Println("主线程结束")
}
首先声明三个管道,第一个intChan是用来存储数据的管道,负责put进去没有处理的数字。
第二个primeChan是用来put进去识别是素数的数字的。
第三个exitChan是用来记录prime是否被处理完了。
intChan := make(chan int, 1000) //intChan 是存放数据的管道
primeChan := make(chan int, 2000) //prime是存放素数的管道
exitChan := make(chan bool, 4)
开启一个putNum协程,接着开启两个primeNum协程。
go putNum(intChan) //这个协程开始 工作了
//开启4个协程,从intChan取出数据,并判断是否为素数,如果是的话就put
for i := 0; i < 4; i++ {
go primeNum(intChan, primeChan, exitChan)
}
如果exitChan这个 管道能够吐出四次数,说明四个协程都关闭了,那么就可以关闭primeChan管道了。
//这里我们的主线程,要进行处理
//直接
go func() {
for i := 0; i < 4; i++ {
<-exitChan
}
//当从exitChan中取出了 4个结果就可以放心的关闭了
close(primeChan)
}()
最终,从primeChan中吐出数字。
for {
res, ok := <-primeChan
if !ok {
break
}
//否则就将结果打印
fmt.Printf("素数=%d\n", res)
}
fmt.Println("主线程结束")