Go 并发实战核心编程【一】

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 -

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值