Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
509 views
in Technique[技术] by (71.8m points)

for select 里使用return一直阻塞

运行以下代码, monitor函数里,有中文描述处. 使用你的浏览器http://localhost:8080/add 会一直阻塞, 为什么?大神解释下.

package main

import (
    "fmt"
    "github.com/gin-gonic/gin"
    "log"
    "math/rand"
    "sync"
)

type Cache struct {
    ch chan int
}
var (
    _cache *Cache
    _once sync.Once
)
func NewCache() *Cache {
    _once.Do(func() {
        _cache = &Cache{
            ch: make(chan int),
        }
        _cache.monitor()
    })
    return _cache
}
func (c *Cache) Push(x int) {
    c.ch <- x

}
func (c *Cache) monitor() {
    go func() {
        for {
            select {
            case result, ok := <-c.ch:
                n := c.N()
                log.Printf("result:%d, ok:%v, n:%d
", result, ok, n)
                if n == 1 {
                    return // 如果换成return 会一直阻塞. 这是为什么?换成break, continue就没事了.
                }
                if ok {
                    log.Println("-----------result:", result)
                }
            default:
                fmt.Println("aaa")
            }
        }
    }()
}
func (c *Cache) N() int {
    return rand.Intn(2)
}

func main() {
    log.SetFlags(log.Lshortfile)
    r := gin.Default()
    r.GET("/add", func(c *gin.Context) {
        NewCache().Push(rand.Intn(1000))
        NewCache().Push(rand.Intn(1000))
        NewCache().Push(rand.Intn(1000))
        NewCache().Push(rand.Intn(1000))
        c.JSON(200, gin.H{
            "x":"ok",
        })
    })
    r.Run(":8080")
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

因为return语法会跳出整个函数调用。

你的代码中,多次调用 NewCache() 只初始化了一个_cache,当你在monitor()使用了return语法,会让整个协程退出,导致c.ch 管道没有消费。所以会阻塞请求。


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...