go通过chan和go func进行并发控制
原文:
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 main() { prochan := make(chan int, 10000) primeChan := make(chan int, 5000) exitChan := make(chan bool, 4) // 1.produce num go producer(prochan) // 2.consume num for i := 0; i < 4; i++ { go consumer(prochan, primeChan, exitChan) } // 3.up a g to wait consumers over go func() { for i := 0; i < 4; i++ { <- exitChan } close(primeChan) }() defer close(exitChan) // 4.main goroutine print the result for v := range primeChan { fmt.Println("main goroutine recv prime number is: ", v) } fmt.Println("main goroutine is over.") } // producer func producer(proChan chan int) { fmt.Println("Producer goroutine 开始生产数据啦!") for i := 1; i <= 10000; i++ { proChan <- i } close(proChan) fmt.Println("Producer goroutine 开始生产结束啦!") } // consumer func consumer(proChan chan int, primeChan chan int, exitChan chan bool) { fmt.Println("Consumer goroutine 开始消费数据啦!") for{ // 1.get num num, ok := <- proChan if !ok { break // producer closed chan } // 2.if is prime number, add to prime chan if isPrimeNum(num) { primeChan <- num } } // 3.the g is over exitChan <- true fmt.Println("Consumer goroutine 退出啦!") } func isPrimeNum(num int) bool { if num == 1 {return true} for i := 2; i < num; i++ { if num % i == 0 {return false} } return true }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
2020-12-21 docker,Dockerfile,docker-compose梳理(1)
2020-12-21 linux ubuntu 的apt-get命令详解