zoukankan      html  css  js  c++  java
  • golang 的 buffered channel 及 unbuffered channel

    The channel is divided into two categories: unbuffered and buffered.

    (1) Unbuffered channel
    For unbuffered channel, the sender will block on the channel until the receiver receives the data from the channel, whilst the receiver will also block on the channel until sender sends data into the channel. Check the following example:

    package main
    
    import (
            "fmt"
            "time"
    )
    
    func main() {
            ch := make(chan int)
    
            go func(ch chan int) {
                    fmt.Println("Func goroutine begins sending data")
                    ch <- 1
                    fmt.Println("Func goroutine ends sending data")
            }(ch)
    
            fmt.Println("Main goroutine sleeps 2 seconds")
            time.Sleep(time.Second * 2)
    
            fmt.Println("Main goroutine begins receiving data")
            d := <-ch
            fmt.Println("Main goroutine received data:", d)
    
            time.Sleep(time.Second)
    }

    The running result likes this:

    Main goroutine sleeps 2 seconds
    Func goroutine begins sending data
    Main goroutine begins receiving data
    Main goroutine received data: 1
    Func goroutine ends sending data
    

    After the main goroutine is launched, it will sleep immediately("Main goroutine sleeps 2 seconds" is printed), and this will cause main goroutine relinquishes the CPU to the func goroutine("Func goroutine begins sending data" is printed). But since the main goroutine is sleeping and can't receive data from the channel, so ch <- 1 operation in func goroutine can't complete until d := <- ch in main goroutine is executed(The final 3 logs are printed).

    (2) Buffered channel
    Compared with unbuffered counterpart, the sender of buffered channel will block when there is no empty slot of the channel, while the receiver will block on the channel when it is empty. Modify the above example:

    package main
    
    import (
            "fmt"
            "time"
    )
    
    func main() {
            ch := make(chan int, 2)
    
            go func(ch chan int) {
                    for i := 1; i <= 5; i++ {
                            ch <- i
                            fmt.Println("Func goroutine sends data: ", i)
                    }
                    close(ch)
            }(ch)
    
            fmt.Println("Main goroutine sleeps 2 seconds")
            time.Sleep(time.Second * 2)
    
            fmt.Println("Main goroutine begins receiving data")
            for d := range ch {
                    fmt.Println("Main goroutine received data:", d)
            }
    }

    The executing result is as follows:

    Main goroutine sleeps 2 seconds
    Func goroutine sends data:  1
    Func goroutine sends data:  2
    Main goroutine begins receiving data
    Main goroutine received data: 1
    Main goroutine received data: 2
    Main goroutine received data: 3
    Func goroutine sends data:  3
    Func goroutine sends data:  4
    Func goroutine sends data:  5
    Main goroutine received data: 4
    Main goroutine received data: 5
    

    In this sample, since the channel has 2 slots, so the func goroutine will not block until it sends the third element.

    P.S., "make(chan int, 0)" is equal to "make(chan int)", and it will create an unbuffered int channel too.

  • 相关阅读:
    SQL性能优化:如何定位网络性能问题
    ORACLE 10升级到10.2.0.5 Patch Set遇到的内核参数检测失败问题
    Linux 僵尸进程查杀
    Linux 虚拟机网络适配器从E1000改为VMXNET3
    v$session中server为none与shared值解析
    SQL SERVER导出特殊格式的平面文件
    XtraBackup出现 Can't connect to local MySQL server through socket '/tmp/mysql.sock'
    CentOS 6.6安装Xtrabackup RPM提示缺少libev.so.4()
    SQL Server Replication 中关于视图的点滴
    ORA-00988: missing or invalid password(s)
  • 原文地址:https://www.cnblogs.com/welhzh/p/9022206.html
Copyright © 2011-2022 走看看