美文网首页
golang 信道总结

golang 信道总结

作者: TimeMage | 来源:发表于2018-02-10 20:18 被阅读529次

    信道channel 概念

    一个可以阻塞程序运行的队列,使用于并发状态下的消息传递

    信道阻塞总结

    • 同步信道(队列大小为0,接发消息立即阻塞)

      • 接收数和发送数不相等

        func err1() {
            c := make(chan int)
            c <- 0
        }
        func err2() {
            c := make(chan int)
            <-c
        }
        
      • 在同一线程接收和发送于同一个同步信道

        func err3() {
            c := make(chan int)
            c <- 0 // 在这一步线程被阻塞了,无法执行到下一步
            <-c
        }
        
    • 异步信道 (有缓冲区)

      • 发送数超过缓冲大小会阻塞

        func err4() {
            c := make(chan int, 1)
            c <- 0
            c <- 0
            <-c
            <-c
        }
        
      • 接收数大于发送数阻塞

        func err5() {
            c := make(chan int, 1)
            <-c
        }
        
      • 发送数大于接受数,但多的部分小于缓冲区容量不阻塞

        func ok1() {
            c := make(chan int, 1)
            c <- 0
        }
        
    • 关闭的信道

      • 再发送或关闭会panic

        func err6() {
            ch := make(chan int)
            close(ch)
            close(ch)
        }
        func err7() {
            ch := make(chan int)
            close(ch)
            ch <- 0
        }
        
      • 再读取

        func test3() {
            ch := make(chan int, 1)
            ch <- 3
            a := 1
            close(ch)
            a, ok := <-ch
            fmt.Println(a, ok)
        }
        //3 true
        func test2() {
            ch := make(chan int)
            close(ch)
            var a = 1
            a, ok := <-ch
            fmt.Println(a, ok)
        }
        //0 false
        
    • 其他情况

      • 在子线程产生死锁,但主线程不同步,程序依然会退出

        func main() {
            go err1()
        }
        

    channel 遍历

    + 两种遍历方式
    
        不确定信道长度的话,发送完最好关闭信道
        ~~~go
        func loop(c chan int) {
            for i := 1; i < 10; i++ {
                c <- i
            }
            for i := 1; i < 1e8; i++ {
                i = i + i - i
            }
            c <- 10
            close(c)
        }
        func forchan(proc func(chan int)) {
            var c = make(chan int)
            go proc(c)
            for k := range c {
                fmt.Printf("%d ", k)
            }
            fmt.Println()
        }
        func whilechan(proc func(chan int)) {
            var c = make(chan int)
            go proc(c)
            for {
                if d, ok := <-c; ok {
                    fmt.Printf("%d ", d)
                    } else {
                        break
                    }
                }
            fmt.Println()
        }
        func main() {
            forchan(loop)
            whilechan(loop)
        }
        ~~~
    + 遍历不清楚长度的channel,如果不close的化会造成死锁
    

    多信道选择 for-select

    语法很简单看书,实现机制不清楚,会不会产生死锁后议

    相关文章

      网友评论

          本文标题:golang 信道总结

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