为了账号安全,请及时绑定邮箱和手机立即绑定

Go并发之魂:Goroutine深入浅出【程序人生中的“米其林三星级”并发实战】

凰凰 架构师
难度初级
时长 1小时58分
学习人数
综合评分8.33
8人评价 查看评价
8.5 内容实用
8.5 简洁易懂
8.0 逻辑清晰
  • fork and join

    查看全部
  • package main
    
    import (
       "fmt"
       "sync"
       "time"
    )
    
    var global = sync.WaitGroup{}
    
    // A车传送给B车的通道
    var ch1 = make(chan *material, 3)
    
    // B车传送给C车的通道
    var ch2 = make(chan *material, 3)
    
    // 食材
    type material struct {
       // 食材名称
       name string
       // 食材数量
       count byte
       // A车处理所需花费时间,单位秒
       elapsedTimeA uint
       // B车处理所需花费时间,单位秒
       elapsedTimeB uint
       // C车处理所需花费时间,单位秒
       elapsedTimeC uint
    }
    
    func main() {
       global.Add(3)
       // 所有需要处理的食材
       materials := []*material{
          {"白菜", 12, 2, 1, 1},
          {"青菜", 12, 1, 1, 1},
          {"胡萝卜", 12, 1, 1, 1},
       }
       start := time.Now()
       go A(materials)
       go B()
       go C()
       global.Wait()
       cost := time.Since(start)
       fmt.Printf("总耗时:%s\n", cost)
    }
    func A(materials []*material) {
       fmt.Printf("A车出发\n")
       // 循环处理每种食材
       for _, ele := range materials {
          var worker = sync.WaitGroup{}
          worker.Add(3)
          // 3名工人分别处理每种食材的1/3
          for i := 0; i < 3; i++ {
             go func(index int, ele2 *material) {
                fmt.Printf("A车工人[%d]正在清洗食材[%s],数量[%d],预计耗时[%d]秒\n", index, ele2.name, ele2.count/3, ele2.elapsedTimeA)
                // 睡眠模拟处理食材耗时
                time.Sleep(time.Second * time.Duration(ele2.elapsedTimeA))
                worker.Done()
             }(i, ele)
          }
          // 等待所有工人都处理完毕后,把处理后的食材传送给B车
          worker.Wait()
          fmt.Printf("A车食材[%s]正在运往B车\n", ele.name)
          ch1 <- ele
       }
       fmt.Printf("A车任务结束\n")
       global.Done()
    }
    
    func B() {
       fmt.Printf("B车出发\n")
       // 循环处理3种食材
       for i := 0; i < 3; i++ {
          // 从通道取不到数据时会阻塞,只有通道关闭时ok才等于false,所以下面的if判断可以忽略
          ele, ok := <-ch1
          if !ok {
             break
          }
          fmt.Printf("B车接收到A车食材[%s]\n", ele.name)
          var worker = sync.WaitGroup{}
          worker.Add(3)
          for j := 0; j < 3; j++ {
             go func(index int, ele2 *material) {
                fmt.Printf("B车工人[%d]正在加工食材[%s],数量[%d],预计耗时[%d]秒\n", index, ele2.name, ele2.count/3, ele2.elapsedTimeB)
                // 睡眠模拟处理食材耗时
                time.Sleep(time.Second * time.Duration(ele2.elapsedTimeB))
                worker.Done()
             }(j, ele)
          }
          // 等待所有工人都处理完毕后,把处理后的食材传送给C车
          worker.Wait()
          fmt.Printf("B车食材[%s]正在运往C车\n", ele.name)
          ch2 <- ele
       }
       fmt.Printf("B车任务结束\n")
       global.Done()
    }
    
    func C() {
       fmt.Printf("C车出发\n")
       for i := 0; i < 3; i++ {
          // 从通道取不到数据时会阻塞,只有通道关闭时ok才等于false,所以下面的if判断可以忽略
          ele, ok := <-ch2
          if !ok {
             break
          }
          fmt.Printf("C车接收到B车食材[%s]\n", ele.name)
          var worker = sync.WaitGroup{}
          worker.Add(3)
          for j := 0; j < 3; j++ {
             go func(index int, ele2 *material) {
                fmt.Printf("C车工人[%d]正在装载食材[%s],数量[%d],预计耗时[%d]秒\n", index, ele2.name, ele2.count/3, ele2.elapsedTimeC)
                // 睡眠模拟处理食材耗时
                time.Sleep(time.Second * time.Duration(ele2.elapsedTimeC))
                worker.Done()
             }(j, ele)
          }
          worker.Wait()
       }
       fmt.Printf("C车任务结束\n")
       global.Done()
    }
    查看全部
  • 终端,pid,IDE
    查看全部
  • context实现goroutine中断
    查看全部
  • 可能习惯了直接听干货知识,讲做菜虽然很生动,但是听起来总感觉别扭。
    查看全部
  • 总结总结总结

    查看全部
  • 面试题之白板写代码

    查看全部
  • 面试题之解题逻梳理

    查看全部
  • 面试题之梳理

    查看全部
  • 面试题之考点

    查看全部
  • 实操案例:生产者和消费者

    查看全部
  • 如何利用 channel 阻塞

    查看全部
  • 企业级解决办法

    查看全部
  • Channel 阻塞的重后果

    查看全部
  • Channe 阻塞条件

    查看全部
首页上一页123下一页尾页

举报

0/150
提交
取消
课程须知
1、学前掌握基本的Go语法基础
老师告诉你能学到什么?
1. multi-goroutine核心机理、使用场景、局限性、如何管理 2. 协程生命周期、多并发通用设计+实战 3. channel使用、资源争抢 4. channel阻塞:概念+触发条件+实际开发场景+避免方法 5. goroutine高频面试题+面试思路点拨 6. 如何白板写goroutine并发面试代码与注意事项

微信扫码,参与3人拼团

意见反馈 帮助中心 APP下载
官方微信
友情提示:

您好,此课程属于迁移课程,您已购买该课程,无需重复购买,感谢您对慕课网的支持!