计算素数 通道 协程之间的关系
并发的俩种思想:
- 第一个通过共享内存,需要锁来保证并发安全。
- 第二个通过通信来。go语言通过channel. channel是协程安全的。
通道 intchan 来传递要计算的数
通道 primechan 来传递结果是素数
通道 exitchan 来保证计算的协程都完毕
协程 inttochan 给intchan输入 1-120000
协程 prime 从intchan获取数,然后将是素数的数输入给primechan ,计算完毕将 bool true输入给exitchan .
协程 exit 从 exitchan获取数据,达到prime协程的个数,就关闭 primechan
协程 printprime 从 primechan获取数据打印。
package main
import (
"fmt"
"sync"
)
var wg sync.WaitGroup
var go_sum_prime int = 16 //计算素数的协程数量
func finttochan(ch chan int) {
defer close(ch) //输出完就关闭
wg.Add(1)
for i := 2; i < 120000; i++ {
ch <- i
}
wg.Done()
}
func fprimechan(intchan chan int, primechan chan int, exitchan chan bool) {
wg.Add(1)
for v := range intchan {
flag := true
for i := 2; i < v; i++ {
if v%i == 0 {
flag = false
break
}
}
if flag {
primechan <- v
}
}
//计算完毕就输出给exitchan
exitchan <- true
wg.Done()
}
func exit(exitchan chan bool, primechan chan int) {
wg.Add(1)
for i := 0; i < go_sum_prime; i++ {
f := <-exitchan
fmt.Printf("i=%v, --> %v ", i, f)
}
close(exitchan)
close(primechan)
wg.Done()
}
func printprime(primechan chan int) {
wg.Add(1)
for v := range primechan {
fmt.Println(v)
}
wg.Done()
}
func main() {
inttochan := make(chan int, 50000)
primechan := make(chan int, 50000)
exitchan := make(chan bool, go_sum_prime)
go finttochan(inttochan)
for i := 0; i < go_sum_prime; i++ {
go fprimechan(inttochan, primechan, exitchan)
}
go printprime(primechan)
go exit(exitchan, primechan)
wg.Wait()
}