package main
import "fmt"
//将数写入管道中
func getNums(getNum chan int) {
for i := 2; i < 200; i++ {
getNum <- i
}
close(getNum)
}
//将管道中的数取出来,判断是否是素数,是的话放入新的管道中
func prineNums(getNum chan int, primeNum chan int, exitStat chan bool) {
//通过死循环取数
for {
v, ok := <-getNum
if !ok {
break
}
//判断是否是素数
flag := true //素数判断标志位
for i := 2; i < v; i++ {
if v%i == 0 { //说明不是素数
flag = false
break
}
}
if flag {
primeNum <- v //将素数存进去
}
}
//取数操作时多个协程共同进行的,里不能close,不知道别的协程是否取数完毕,只能判断当前取数的协程
fmt.Println("这里有一个协程取数完毕~~")
//将完毕标志位放进去
exitStat <- true
}
func main() {
//创建三个管道
//从8000取数放到管道
getNum := make(chan int, 1000)
//从管道中取素数放到新的管道
primeNum := make(chan int, 1000)
//标志位管道,判断程序协程是否执行完毕
exitStat := make(chan bool, 4) //四个协程
//首先放进去数
getNums(getNum)
//然后四个协程筛选素数
for i := 0; i < 4; i++ {
go prineNums(getNum, primeNum, exitStat)
}
//判断四个协程是否全部执行完毕、
for i := 0; i < 4; i++ {
<-exitStat //啥时候能取完,说明四个协程都运行结束
}
//关闭存素数管道,打印素数
close(primeNum)
for {
v, ok := <-primeNum //取数据
if !ok {
break
}
fmt.Println(v)
}
}
输出结果
加入了时间统计功能,使用的是time包中的time.Now().Unix()
,并且将exitStat使用匿名函数封装起来并通过协程运行
package main
import (
"fmt"
"time"
)
//将数写入管道中
func getNums(getNum chan int) {
for i := 2; i < 700000; i++ {
getNum <- i
}
close(getNum)
}
//将管道中的数取出来,判断是否是素数,是的话放入新的管道中
func prineNums(getNum chan int, primeNum chan int, exitStat chan bool) {
//通过死循环取数
for {
v, ok := <-getNum
if !ok {
break
}
//判断是否是素数
flag := true //素数判断标志位
for i := 2; i < v; i++ {
if v%i == 0 { //说明不是素数
flag = false
break
}
}
if flag {
primeNum <- v //将素数存进去
}
}
//取数操作时多个协程共同进行的,里不能close,不知道别的协程是否取数完毕,只能判断当前取数的协程
fmt.Println("这里有一个协程取数完毕~~")
//将完毕标志位放进去
exitStat <- true
}
func main() {
//创建三个管道
//从8000取数放到管道
getNum := make(chan int, 1000)
//从管道中取素数放到新的管道
primeNum := make(chan int, 700000)
//标志位管道,判断程序协程是否执行完毕
exitStat := make(chan bool, 4) //四个协程
starttime := time.Now().Unix() //time.Now().Unix()
//首先放进去数,也使用协程
go getNums(getNum)
//然后四个协程筛选素数
for i := 0; i < 4; i++ {
go prineNums(getNum, primeNum, exitStat)
}
//判断四个协程是否全部执行完毕、这里用匿名函数封装起来,同样使用协程运行
go func() {
for i := 0; i < 4; i++ {
<-exitStat //啥时候能取完,说明四个协程都运行结束
endtime := time.Now().Unix()
//统计协程运行时间
fmt.Println("使用协程耗费时间=", endtime-starttime)
}
close(primeNum) //关闭存素数管道,才可以打印素数
}()
//主线程,打印素数
for {
v, ok := <-primeNum //取数据
if !ok {
break
}
fmt.Println(v)
}
fmt.Println("主线程执行完毕~~")
}