```go
package main
import (
"fmt"
_ "reflect"
"sync"
"time"
)
func writeData(intChan chan int) {
for i := 1; i <= 8000; i++ {
intChan <- i
//fmt.Printf("writeData()写入数据%v", i)
}
close(intChan)
//fmt.Println(intChan)
}
func judgData(intChan chan int, resultChan chan int, exitChan chan bool, done func()) {
defer done()
time.Sleep(time.Millisecond * 1000)
flag := true
//time.Sleep(time.Second *1)
for {
num, ok := <-intChan
if !ok {
fmt.Println("已从intChan读取所有数据")
break
}
for i := 2; i < num; i++ {
if num % i == 0 {
flag = false
break
}
if flag {
resultChan <- num
fmt.Printf("添加%v到resultChan\n", num)
}
}
}
fmt.Println("协程执行完毕")
exitChan <- true
}
func main() {
var wg sync.WaitGroup
intChan := make(chan int, 10000)
resultChan := make(chan int, 20000)
exitChan := make(chan bool, 8)
go writeData(intChan)
for i := 0; i < 8; i++ {
go judgData(intChan, resultChan, exitChan, wg.Done)
}
//go func() {
// for i := 0 ; i < 8 ; i ++ {
// key := <-exitChan
// fmt.Print(key)
// }
// close(resultChan)
//}()
wg.Add(8)
wg.Wait()
close(resultChan)
func() {
for i := 0; i < 8; i++ {
key := <-exitChan
fmt.Printf("key=%v\n", key)
}
}()
for {
res, ok := <-resultChan
if !ok {
break
}
fmt.Printf("素数=%d\n", res)
}
}
```
更新后的代码如下,可以正常工作,就是感觉不够优雅
```go
package main
import (
"fmt"
_ "sync"
)
func writeData(intChan chan int) {
for i := 1; i < 80; i++ {
intChan <- i
}
fmt.Println("writeData()执行完毕")
fmt.Println("关闭intChan")
close(intChan)
}
func judgData(intChan chan int, resultChan chan int, exitChan chan bool) {
//time.Sleep(time.Millisecond *100)
//fmt.Println("开始读取intChan")
flag := true
for {
flag = true //重置标志位,因为后面这个值被设置为false了
num, ok := <-intChan
if !ok {
fmt.Println("数据读取完毕")
break
}
for a := 2; a < num; a++ {
if num%a == 0 {
flag = false
break
}
}
if flag {
resultChan <- num
}
}
exitChan <- true
fmt.Println("一个协程执行完毕")
}
func main() {
intChan := make(chan int, 10000)
resultChan := make(chan int, 10000)
exitChan := make(chan bool, 8)
//var wgw sync.WaitGroup
//var wgr sync.WaitGroup
//wgw.Add(1)
//wgr.Add(8)
go writeData(intChan)
//go writeData(intChan, wgw.Done)
//wgw.Wait()
//close(intChan)
for i := 0; i < 8; i++ {
go judgData(intChan, resultChan, exitChan)
}
go func() {
for sec := 0; sec < 8; sec++ {
<-exitChan //如果没有值就会等待值写入,造成主线程的阻塞
}
close(resultChan)
}() // 这里用协程是不让这个取值堵塞主线程的取值
//time.Sleep(time.Second *10)
//wgr.Wait()
for {
key, ok := <-resultChan
if !ok { //这里会因为上面的协程没结束,没有关闭resultChan,ok的值一直未true而阻塞一直到所有协程执行完毕
break
}
fmt.Printf("素数:%v\n", key)
}
}
```
#6
更多评论