• go 通道的运用


    无缓冲通道:同步通道

    //对无缓冲channel类型的发送与接收操作,一定要放在两个不同的Goroutine中进行,否则会导致deadlock。
    //无缓冲通道,必须接收和发送都准备好了才能执行。否则会阻塞。
    //所以无缓冲通道相当于是同步通道了。
    var helloChan = make(chan struct{})
    
    func Test33() {
    	fmt.Println("数一下羊吧~~~")
    	go SaySheep()
    	<-helloChan //这里会暂时阻塞直到SaySheep遍历执行输出10只羊后收到helloChan通道发送的值才会继续下一步
    	fmt.Println("you are bad bad")
    }
    
    func SaySheep() {
    	for i := 0; i < 10; i++ {
    		fmt.Println("🐏")
    	}
    	helloChan <- struct{}{} //空结构体不占用内存
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    输出结果:
    在这里插入图片描述

    有缓冲通道:控制协程、并发的数量

    //利用有缓冲通道控制协程的数量,利用waitGroup控制协程的结束
    var wg sync.WaitGroup
    
    func Test35() {
    	//利用有缓冲通道控制协程数量为3
    	ch := make(chan struct{}, 3)
    	for i := 0; i < 20; i++ {
    		wg.Add(1)
    		//这里缓冲通道写满了3个数据后,就会阻塞,等待Weekend方法中发送通道里的数据,才能继续执行
    		ch <- struct{}{}
    		go Weekend(ch, i)
    	}
    	wg.Wait()
    }
    
    func Weekend(ch chan struct{}, i int) {
    	fmt.Println("周末拉", i)
    	fmt.Println(" goroutine count = ", runtime.NumGoroutine())
    	// time.Sleep(time.Duration(i) * time.Second)
    	<-ch
    	wg.Done()
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    输出结果:
    在这里插入图片描述

    无缓冲通道也可以控制并发的数量

    //无缓冲通道控制协程数量
    //思想:开启固定的goroutine池,然后设置无缓冲的通道作为接收任务的中介,固定的协程读取到通道中任务就执行任务。
    var wg sync.WaitGroup
    
    func Test36() {
    	var cowChan = make(chan string)
    	var go_num = 3 //指定协程的数量为3
    	for i := 0; i < go_num; i++ {
    		go CallCowBoy(cowChan)
    	}
    	for i := 0; i < 20; i++ {
    		SendTask(cowChan, i)
    		//也可以直接写在这里
    		// wg.Add(1)
    		// cowChan <- "🐂🤠" + strconv.Itoa(i)
    	}
    	wg.Wait()
    }
    
    func CallCowBoy(ch chan string) {
    	for v := range ch {
    		fmt.Printf("%s are very busy \n", v)
    		fmt.Println(" goroutine count = ", runtime.NumGoroutine())
    		wg.Done()
    	}
    }
    
    func SendTask(ch chan string, i int) {
    	wg.Add(1)
    	ch <- "🐂🤠" + strconv.Itoa(i)
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
  • 相关阅读:
    低代码平台:通过可视化的开发工具和组件库,可快速地构建应用程序,从而实现快速迭代和升级
    从电影《沙丘》说起——对人工智能的思考
    B+树索引(7)之索引适用场景(上)
    Django5 -----表单与通用视图系统
    [附源码]计算机毕业设计JAVA后疫情下物业管理系统
    软件定义卫星:数字卫星实践
    【Loadrunner】学习loadrunner——性能测试基础篇(一)
    R语言非参数检验多重比较
    python 图像相减的不同方法
    JavaIO进阶系列——BIO day1-2
  • 原文地址:https://blog.csdn.net/weixin_38155824/article/details/125445693