Go-协程求素数+管道的注意事项
协程求素数
package main
import (
"fmt"
"time"
)
func putNum(intChan chan int) {
for i := 1; i <= 8000; i++ {
intChan <- i
//fmt.Println("写入数据", i)
}
close(intChan)
}
func primeNum(intChan chan int, primeChan chan int, exitChan chan bool) {
for {
time.Sleep(time.Millisecond * 10)
num, ok := <-intChan
if !ok {
break
}
//判断num是不是素数
flag := true
for i := 2; i < num; i++ {
if num%i == 0 {
flag = false
break
}
}
if flag {
primeChan <- num
}
}
fmt.Println("有一个primeNum 协程取不到数据了,退出")
exitChan <- true
}
func main() {
intChan := make(chan int, 1000)
primeChan := make(chan int, 2000)
exitChan := make(chan bool, 4)
//intChan放人1-8000个数
go putNum(intChan)
//开启四个协程 从intChan中取出数据 并判断是否为素数
//如果是就放入primeChan
for i := 0; i < 4; i++ {
go primeNum(intChan, primeChan, exitChan)
}
//判断主线程的关闭
go func() {
for i := 0; i < 4; i++ {
<-exitChan
}
//当我们取出了4个结果 就可以放心的关闭了
close(primeChan)
}()
for {
res, ok := <-primeChan
if !ok {
break
}
fmt.Printf("素数=%d\n", res)
}
fmt.Println("主线程退出")
}
管道只读只写
package main
import "fmt"
func main() {
//管道可以声明为只读只写
//只写
chan2 := make(chan<- int, 3)
chan2 <- 20
fmt.Println("chan2=", chan2)
//只读
var chan3 <-chan int
num2 := <-chan3
fmt.Println("num2", num2)
}
Select语句 解决拥塞控制
package main
import "fmt"
func main() {
intChan := make(chan int, 10)
for i := 0; i < 10; i++ {
intChan <- i
}
stringChan := make(chan string, 5)
for i := 0; i < 5; i++ {
stringChan <- "hello" + fmt.Sprintf("%d", i)
}
//如果不关闭管道 会发生死锁
//可以用select解决这个问题
for {
select {
case v := <-intChan:
fmt.Printf("从intChan读取的数据%d\n", v)
case v := <-stringChan:
fmt.Printf("从stringChan读取的数据%s\n", v)
default:
fmt.Printf("加入逻辑\n")
return
}
}
}
转载请注明出处,欢迎讨论和交流!