一次golang deadlock的討論

背景

在微信群一位同學(xué)拋出的一段代碼, 各位看官猜想一下程序的執(zhí)行結(jié)果

// 程序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
    }
}

我猜想大部分同學(xué)都會說是: fatal error: all goroutines are asleep - deadlock!. 因為waitQueue是個沒有緩沖的channel, waitQueue <- 1向里面send一個值, 理論上程序一運(yùn)行就會報deadlock的錯誤

如下面這個例子

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

這個程序的結(jié)果毫無疑問是: fatal error: all goroutines are asleep - deadlock!

但是文章一開頭的這個程序, 同學(xué)們在自己機(jī)器上運(yùn)行一下, 我想99%的人應(yīng)該得到的是下面的結(jié)果: running, not deadlock

我甚至把程序?qū)懙母鼧O端些

// 程序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, 依然不會出現(xiàn)deadlock

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

我分別在macOS, linux, ubuntu上面驗證了1.10, 1.12.2, 1.12.5, 1.12.6都不會出現(xiàn)deadlock

于是我在golang的GitHub上提了這個issue, bcmills很快回復(fù)了為什么不會出現(xiàn)deadlock的提示. 他的大概意思是golang built-in deadlock detector 在某些情況下是被禁用, 如通過C庫進(jìn)行系統(tǒng)調(diào)用. deadlock detector觸發(fā)依賴于goroutine的調(diào)度和系統(tǒng)調(diào)用的具體實(shí)現(xiàn). deadlock detector是一個有用的工具, 但是不能完全替代集成測試和負(fù)載測試

deadlock2
deadlock1
deadlock

具體討論內(nèi)容可以查看: https://github.com/golang/go/issues/33004

也不是說所有的環(huán)境下都不會出現(xiàn)deadlock, 至少在golang playground就出現(xiàn)了

deadlock

具體在往深處我就沒有去追究built-in deadlock detector的實(shí)現(xiàn)了, 等后面再補(bǔ)充這個. 不過從這里也可以看出來, 我們不能還是要寫好單元測試, 集成測試等避免goroutine leaks出現(xiàn), 不能過分依賴與deadlock detector

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容