美文网首页程序员
golang goroutine和channel

golang goroutine和channel

作者: luckyase | 来源:发表于2018-08-08 11:56 被阅读0次

无buffer的chan,buffer=0的chan

从ch中取数据。
如果ch中没有传入数据,程序将一直阻塞在<-ch这里

//无buffer的chan
ch := make(chan int)
//从ch中取数据
<-ch//如果ch中没有传入数据,程序将一直阻塞在这里

往ch中写数据。
如果ch中没有可以写入数据,则程序会阻塞在ch<-1这里

//无buffer的chan
ch := make(chan int)
ch<-1

有buffer的chan

只影响chan的写入,如果chan的buffer已经满了(比如,chan中的数据没有被消费或者chan中的数据消费比生产要慢),则程序会阻塞在ch<-1这里

//有buffer的chan
ch := make(chan int,2)
ch<-1
fmt.Println(1)
ch<-1
fmt.Println(2)
ch<-1//会阻塞在这里
fmt.Println(3)

无buffer的chan的发送操作总是在接受前完成(操作是指执行顺序,而不是代码编写顺序)。

注意:close chan,<-chan将接收到chan的零值

不建议的使用方式

    end := make(chan int64, 0)
    var a int64
    go func() {
        a = <-end
        fmt.Println(999)//此行代码很有可能无法输出
    }()
    end <- 1
    fmt.Println(a)

因为buffer为0,end <- 1此行会被阻塞,直到a = <-end被执行,一旦a = <-end被执行,end <- 1会立刻发送数据,程序执行fmt.Println(a),执行到这里,程序就结束了。fmt.Println(999)很大可能无法及时执行。
如果buffer不为0,写数据不会被阻塞,则程序立刻结束了,goroutine中的代码很可能无法执行。

建议的使用方式

先写数据,再读数据。
解释:写数据一般可能会有时间消耗,比如写入的数据是从cache或者db中读取的。在goroutine中执行耗时操作也比较合理。

    end := make(chan int64)

    go func() {
        end <- 1
    }()

    fmt.Println(<-end)

读数据也可以在goroutine中执行


    count := 0
    
    end := make(chan int64, 20)

    go func() {
        for i := 0; i < 10; i++ {
            end <- int64(i)
        }
    }()

    go func() {
        for v := range end {
            count++
            fmt.Println(v, count)
        }
    }()

    http.HandleFunc("/state", func(writer http.ResponseWriter, request *http.Request) {
        io.WriteString(writer, "count is "+strconv.Itoa(count))
    })
    http.ListenAndServe(":7777", nil)

相关文章

网友评论

    本文标题:golang goroutine和channel

    本文链接:https://www.haomeiwen.com/subject/ivpavftx.html