美文网首页
一次golang deadlock的讨论

一次golang deadlock的讨论

作者: HHFCodeRv | 来源:发表于2019-07-11 11:34 被阅读0次

背景

在微信群一位同学抛出的一段代码, 各位看官猜想一下程序的执行结果

// 程序1
func main() {
    fmt.Println("running, not deadlock")
    server, err := net.Listen("tcp", "127.0.0.1:9001")
    if err != nil {
        fmt.Println(err)
    }

    waitQueue := make(chan int)
    for {
        connection, err := server.Accept()
        if err != nil {
            panic("server")
        }
        fmt.Printf("Received connection from %s.\n", connection.RemoteAddr())
        waitQueue <- 1
    }
}

我猜想大部分同学都会说是: fatal error: all goroutines are asleep - deadlock!. 因为waitQueue是个没有缓冲的channel, waitQueue <- 1向里面send一个值, 理论上程序一运行就会报deadlock的错误

如下面这个例子

// 程序1
func main() {
    waitQueue := make(chan int)
    for {
        waitQueue <- 1
    }
}

这个程序的结果毫无疑问是: fatal error: all goroutines are asleep - deadlock!

但是文章一开头的这个程序, 同学们在自己机器上运行一下, 我想99%的人应该得到的是下面的结果: running, not deadlock

我甚至把程序写的更极端些

// 程序3
func main() {
    fmt.Println("running, not deadlock")
    waitQueue := make(chan int)
    waitQueue <- 1
    return

    server, err := net.Listen("tcp", "127.0.0.1:9001")
    if err != nil {
        fmt.Println(err)
    }

    for {
        connection, err := server.Accept()
        if err != nil {
            panic("server")
        }
        fmt.Printf("Received connection from %s.\n", connection.RemoteAddr())
    }
}

程序3和程序1不同的地方是: 我把整个channel放在了程序开始, 甚至直接return, 依然不会出现deadlock

是不是陷入了深深的怀疑之中?

我分别在macOS, linux, ubuntu上面验证了1.10, 1.12.2, 1.12.5, 1.12.6都不会出现deadlock

于是我在golang的GitHub上提了这个issue, bcmills很快回复了为什么不会出现deadlock的提示. 他的大概意思是golang built-in deadlock detector 在某些情况下是被禁用, 如通过C库进行系统调用. deadlock detector触发依赖于goroutine的调度和系统调用的具体实现. deadlock detector是一个有用的工具, 但是不能完全替代集成测试和负载测试

deadlock2 deadlock1 deadlock

具体讨论内容可以查看: https://github.com/golang/go/issues/33004

也不是说所有的环境下都不会出现deadlock, 至少在golang playground就出现了

deadlock

具体在往深处我就没有去追究built-in deadlock detector的实现了, 等后面再补充这个. 不过从这里也可以看出来, 我们不能还是要写好单元测试, 集成测试等避免goroutine leaks出现, 不能过分依赖与deadlock detector

相关文章

  • 一次golang deadlock的讨论

    背景 在微信群一位同学抛出的一段代码, 各位看官猜想一下程序的执行结果 我猜想大部分同学都会说是: fatal e...

  • Golang系列1之deadlock

    因为公司安排,我临时从Java项目组调往Go项目组,经过差不多5天业余时间对Go学习后,架构师让我给公司同事进行了...

  • Ch8 Deadlock

    Chapter 8 : Deadlock System model Deadlock Characterizati...

  • 【The Java™ Tutorials】【Concurrenc

    Deadlock Deadlock describes a situation where two or more...

  • golang面试基础系列-解锁deadlock(四)

    在 go 中经常会使用 channel,进行并发执行子任务,提高执行效率。但一不小心就会踩到 deadlock 的...

  • Delete&Insert引发的Mysql死锁

    近日遇到一个比较奇怪的deadlock错误, 错误详情: Deadlock found when trying t...

  • Deadlock

    DeadLock 无论在硬件层面还是软件层面,都有可能出现多device多user的情景,如果不能恰当地分配资源那...

  • MySQL进阶

    引擎 MyISAM:deadlock free。一次获取所需的全部锁。读性能高,内存使用率高。InnoDB:逐步加...

  • DeadLock Example

    start end

  • go deadlock

    死锁 何谓死锁? 操作系统有讲过的,所有的线程或进程都在等待资源的释放。如上的程序中, 只有一个goroutine...

网友评论

      本文标题:一次golang deadlock的讨论

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