V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
xing393939
V2EX  ›  Go 编程语言

go 协程和 select 的知识点

  •  
  •   xing393939 ·
    xing393939 · 2020-12-04 20:31:35 +08:00 · 1127 次点击
    这是一个创建于 1484 天前的主题,其中的信息可能已经有所发展或是发生改变。

    无缓存管道和缓存管道

    先看看无缓存管道的例子:

    	a := make(chan bool)
    	go func() {
    		log.Println("goroutine")
    		<-a
    	}()
    	a <- true
    

    这里主协程会等待子协程执行完,但是如果把第一行改成 a := make(chan bool, 1),那么主协程写完消息直接退出了,子协程没有机会执行(只有一个 cpu 时)。但是改成如下子协程又可以执行了:

    	a := make(chan bool, 1)
    	go func() {
    		log.Println("goroutine")
    		<-a
    	}()
    	a <- true
    	a <- true
    

    管道关闭后,select 能一直接受 close 信号

    	a := make(chan bool, 1)
    	go func() {
    		close(a)
    	}()
    	for {
    		select {
    		case _, ok := <-a:
    			log.Println(ok)
    		}
    	}
    

    而用 for range 是不能获取 close 信号的,如下:

    	a := make(chan bool, 1)
    	go func() {
    		a <- true
    		close(a)
    	}()
    	for {
    		for v := range a {
    			log.Println(v)
    		}
    	}
    
    
    1 条回复    2020-12-05 00:51:07 +08:00
    user8341
        1
    user8341  
       2020-12-05 00:51:07 +08:00
    range 是循环到 chan 被关闭为止。当然如果一开始就是关闭的,循环就不执行。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2378 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 15:57 · PVG 23:57 · LAX 07:57 · JFK 10:57
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.