通过4个小案例入门 goruntine与channel 的 综合使用
所需基础:
- 了解并发/并行概念
- 了解Go的MPG模式
- 熟悉goruntine,channel的基本操作
案例1
开启一个write协程 向管道 intChan 写入 50个整数
开启两个read协程 从管道 intChan 读取write写入的数据
write 和 read 操作 的是同一个 管道
!!主线程 需要等待writeData 和 readData 协程都完成工作后才能退出!!
目的:初识 goruntine与channel 如何综合使用
分析:
- write协程(存入数据) 以及 read协程(取出数据) 同时操作 intChan 管道 , 何时取完(主线程等多久)?多定义一个通道exitChan 用于管理 状态
代码:
package main
import (
"fmt"
)
var (
intChan = make(chan int,50)
exitChan = make(chan bool,1)
)
func write(){
for i:=0;i<=50;i++{
intChan<-i
}
close(intChan)
}
func read(){
// for遍历intChan
for ;;{
v,ok:=<-intChan
// 取不出来
if !ok {
break
}
fmt.Println("Date = ",v)
}
exitChan<- true
}
func main(){
go write()
for i:=0;i<2;i++{//for循环 起 两个协程
go read()
}
//主线程循环等待
for ;;{
if len(exitChan) == 1{
fmt.Println("协程完成任务了")
close(exitChan)
break
}
}
}
goruntine与channel 综合使用
大致框架:
func main(){
业务逻辑用的通道
exitChan 关闭 goruntine 用的通道
for i:=0;i<=8;i++{//启动9个协程 //启动多个协程
go func(){
业务逻辑
exitChan<- true
}()
}
for;;{
if len(exitChan) == max {
close(业务逻辑通道)
close(exitChan) //可关可不关
break
}
}
}
案例2
要求统计1-200000 的数字中 哪些是素数
goruntine + channel 解决
分析:
- 起一个协程(putNum) 取1-200000的数字放入intChan管道中 放完立刻关闭intChan
- 起多个协程(primerNum) 取intChan管道的数 计算并找出 1- 200000中的素数放入primeChan管道中
- 让主线程等待 开启exitChan 管道 存放协程(primerNum)工作情况
代码:
package main
import (
"fmt"
)
func putNum(intChan chan int){
for i:=1;i<=200000;i++{
intChan<-i
}
close(intChan)
}
func primeNum(intChan chan int,primeChan chan int, exitChan chan bool){
var num int
var flag bool
for;;{
num = <-intChan
//空管道处理 退出for
if len(intChan)==0{
break
}
// 判断是否为素数 除了自己和本身能够整除 其他不能整除
flag = true // 默认为素数
for i:=2;i<num;i++{
if num % i == 0{//不是素数
flag = false
break
}
}
if flag{
primeChan<- num
}
}
fmt.Println("协程工作完成!!!")
exitChan<-true
}
func main(){
intChan:=make(chan int,1000)
primeChan:=make(chan int,20000)
exitChan:=make(chan bool,4)
go putNum(intChan)
for i:=0;i<4;i++{
go primeNum(intChan,primeChan,exitChan)
}
//阻塞主线程处理
for ;;{
if len(exitChan) == 4{
fmt.Println("主线程即将结束")
close(primeChan)
close(exitChan)
break
}
}
for v:=range primeChan{
fmt.Printf("%v 是素数\n",v)
}
}
案例练习1
启动一个协程 将1-2000 的数放入到一个channel
启动 8 个协程 从 通道 取出 数 并且计算1+...+n的值 并存到另一个管道 resChan
最后8个协程 协同 完成 ,在遍历resChan , 显示结果 如[res[1]= 1...res[10]=55]
案例练习2
开十个协程 writeDataFile 随机生成1000个数据,存放到文件中
当writeDataFile完成写1000个数据到文件后,起10个协程sort从文件中读取1000个数据并排序,存放到10个不同的文件中