golang fatal error: all goroutines are asleep - deadlock!

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

轉自:http://studygolang.com/articles/2410

channel預設上是阻塞的,也就是說,如果Channel滿了,就阻塞寫,如果Channel空了,就阻塞讀。阻塞的含義就是一直等到輪到它為止。單有時候我們會收到 fatal error: all goroutines are asleep - deadlock!  異常,這是如何呢?

代碼例子:

package main

import "fmt"

func main() {
    channel := make(chan string, 2)

    fmt.Println("1")
    channel <- "h1"
    fmt.Println("2")
    channel <- "w2"
    fmt.Println("3")
    channel <- "c3"    // 執行到這一步,直接報 error
    fmt.Println("...")
    msg1 := <-channel
    fmt.Println(msg1)
}

執行效果:

參考:

http://stackoverflow.com/questions/26927479/go-language-fatal-error-all-goroutines-are-asleep-deadlock

 

fatal error: all goroutines are asleep - deadlock!

出錯資訊的意思是:
在main goroutine線,期望從管道中獲得一個資料,而這個資料必須是其他goroutine線放入管道的
但是其他goroutine線都已經執行完了(all goroutines are asleep),那麼就永遠不會有資料放入管道。
所以,main goroutine線在等一個永遠不會來的資料,那整個程式就永遠等下去了。
這顯然是沒有結果的,所以這個程式就說“算了吧,不堅持了,我自己自殺掉,報一個錯給代碼作者,我被deadlock了”

 

這裡是系統自動在除了主協程之外的協程都關閉後,做的檢查,繼而報出的錯誤, 證明思路如下, 在100秒內, 我們看不到異常, 100秒後,系統報錯。

package main

import (
    "fmt"
    "time"
)

func main() {
    channel := make(chan string, 2)

    go func() {
        fmt.Println("sleep 1")
        time.Sleep(100 * time.Second)
        fmt.Println("sleep 2")
    }()

    fmt.Println("1")
    channel <- "h1"
    fmt.Println("2")
    channel <- "w2"

    fmt.Println("3")
    channel <- "c3"

    fmt.Println("...")
    msg1 := <-channel
    fmt.Println(msg1)
}

100秒內執行效果:

100秒後執行效果:

 

如果避免上面異常拋出呢?這時候我們可以用 select來幫我們處理。

package main

import "fmt"

func main() {
    channel := make(chan string, 2)

    fmt.Println("1")
    channel <- "h1"
    fmt.Println("2")
    channel <- "w2"

    fmt.Println("3")
    select {

    case channel <- "c3":
        fmt.Println("ok")
    default:
        fmt.Println("channel is full !")
    }

    fmt.Println("...")
    msg1 := <-channel
    fmt.Println(msg1)
}

執行效果:

這時候,我們把第三個要寫入的 chan 拋棄了。

 

上面的例子中是寫的例子, 讀的例子也一樣,下面的異常是  ws := <-channel 這一行拋出的。

channel := make(chan string, 2)

fmt.Println("begin")
ws := <-channel
fmt.Println(ws)


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.