Go 并发实战核心编程【一】
1. 需求
-
启动一个goroutine,将1-10000的数字放入chan中 -
启动4个goroutine从chan中读取数字,并计算是不是素数 -
是素数就讲结果放入结果chan中 -
最后遍历结果chan,打印素数集合
2. 思路
这道题思路很简单,首先明确一个点就是这个需求有三种类型的goroutine:
-
第一种类型就是生产者,它主要负责数据的生产; -
第二种类型就是消费者,他主要负责消费数据做加工; -
第三种类型就是main goroutine,他主要负责调度这些goroutine并且等待他们退出。
明确思路之后我们在深入分析下,这个需求需要三个chan:
-
第一个就是生产者和消费者之间的通信是需要一个chan的,这个chan就是生产者生产数字放到chan中,消费者从chan取出数字。 -
第二个就是消费者计算完素数之后结果得放入一个chan中,这个chan需要和main goroutine通信,因为main goroutine需要遍历打印这些素数; -
最后一个就是main goroutine需要等待所有消费goroutine的退出,因为我不知道消费者什么时候结束,所以也需要一个chan和main goroutine通信。
因此这个需求需要三种类型的goroutine和三种类型的chan。
3. 编码
package main
import "fmt"
// 生产者
func producer(intChan chan int) {
fmt.Println("producer goroutine 开始生产数据啦")
for i:=1; i<10000; i++ {
intChan <- i
}
//生产完毕就关闭
close(intChan)
fmt.Println("producer goroutine 退出啦")
}
// 消费者
func consumer(intChan chan int, primeChan chan int, exitChan chan bool) {
fmt.Println("consumer goroutine 开始消费数据啦")
for {
num, ok := <- intChan
if !ok {
break //生产者已经关闭intChan 那么消费者读取到关闭信号之后就应该退出
}
//计算素数
flag := true
for i:=2; i<num; i++ {
if num%i == 0 {
flag = !flag
break
}
}
//素数存储到primeChan中
if flag {
primeChan <- num
}
}
// 处理结束之后 退出
exitChan <- true
fmt.Println("consumer goroutine 退出啦")
}
func main() {
intChan := make(chan int, 10000)
exitChan := make(chan bool, 4)
primeChan := make(chan int, 5000)
// 起一个goroutine生产数据
go producer(intChan)
// 起四个goroutine消费数据
for i:=0; i<4; i++ {
go consumer(intChan, primeChan, exitChan)
}
// 起一个goroutine等待消费者goroutine退出 并且退出之后关闭结果chan(primeChan)
// 这里可以在main goroutine中直接同步等待退出,但是考虑到并发特性,还是go func出去等,不要阻塞main goroutine
go func() {
for i:=0; i<4; i++ {
<- exitChan
}
close(primeChan)
}()
//main goroutine 打印结果
for v := range primeChan {
fmt.Println("main goroutine 接收到的素数是:", v)
}
fmt.Println("main goroutine 退出啦")
}
4. 小结
-
谁负责生产数据到chan,谁就负责关闭chan -
谁最后处理完chan中数据,就应该通知调用方自己退出了 -
main goroutine一定是程序最后一个goroutine退出的
– END –
原文始发于微信公众号(堆栈future):Go 并发实战核心编程【一】
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/103540.html