美文网首页
channel 和阻塞模式和非阻塞模式(1)

channel 和阻塞模式和非阻塞模式(1)

作者: 上弦月Tt | 来源:发表于2020-07-16 00:34 被阅读0次

    最近一直又被问到chan 的阻塞和非阻塞模式有什么区别,他们分别在什么场景下使用,写个日记记录下

    阻塞模式

    示例代码

    package main
    
    import (
        "fmt"
        "time"
    )
    
    func main() {
        ch := make(chan int)
        ch <- 1
        time.Sleep(3 * time.Second)
        i := <-ch
        fmt.Println(i)
    }
    

    很明显以上代码会报错fatal error: all goroutines are asleep - deadlock!,非阻塞channel同一时刻必须有读端(i=:<-ch)和写端(ch <- 1),可以理解为一个同步过程,所以有的地方把他叫做同步通道, 修改代码如下就可以正常运行.

    package main
    
    import (
        "fmt"
        "time"
    )
    
    func main() {
        ch := make(chan int)
        go func() {
            ch <- 1
            time.Sleep(3 * time.Second)
        }()
        i := <-ch
        fmt.Println(i)
    }
    

    应用场景:阻塞主程序,如果能捕获系统Interrupt信号,则退出主程序,执行清理工作, 示例代码如下

    func Consumer() {
        // do something
        stop := make(chan os.Signal)
    
        signal.Notify(stop, os.Interrupt)
        <-stop
        endProcess()
    }
    
    func endProcess() {
        fmt.Println("我来结束程序")
        time.Sleep(3 * time.Second)
    }
    

    如果使用select 程序永远都不会报fatal error: all goroutines are asleep - deadlock!如下所示

    package main
    
    import (
        "fmt"
        "time"
    )
    
    func main() {
        messages := make(chan string)
        signals := make(chan bool)
    
        select {
        case msg := <-messages:
            fmt.Println("received message", msg)
        default:
            fmt.Println("no message received")
        }
    
        go func() { messages <- "hi" }()
        time.Sleep(1 * time.Second)
        
    
        select {
        case msg := <-messages:
            fmt.Println("received message", msg)
        case sig := <-signals:
            fmt.Println("received signal", sig)
        default:
            fmt.Println("no activity")
        }
    }
    

    明天争取把非阻塞的通道补上。

    相关文章

      网友评论

          本文标题:channel 和阻塞模式和非阻塞模式(1)

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