Go語言學習日誌之channel引發死鎖問題

2021-10-13 21:06:30 字數 2109 閱讀 7237

今天在看到go中的channel時,就自己動手試了一下這個資料結構,先貼原始**:

package main

import

("fmt"

"time"

)func

main()

}

乍一看沒毛病,但就是這麼簡單的乙個測試執行就直接報錯了:

fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan send]:

main.main(

) d:/workspace/go/golearning/channeltest.go:12 +0x65

process finished with exit code 2

這就往裡面寫了兩個字串,然後再讀出來,怎麼就死鎖了呢?

然後我就查到了這位大佬的資料,先貼上煉接以示尊敬:

下面附上我自己綜合別的資料的理解:

首先,使用ch :=make(chan string)建立的channel是無快取的,這就意味著<-ch這句會被阻塞直到接收到資料才被執行。並且當使用ch <-"abc"進行寫的時候,協程也會被阻塞直到有語句對這個channel進行讀操作,而main函式的執行在go語言中本身就是乙個協程的執行,所以在執行到c<-'a』的時候,執行main函式的協程將被阻塞,進而fmt.println(<-ch)也將被阻塞無法執行,所以發生了死鎖。

根據這位大佬的方法,將讀和寫操作寫在不同的協程中,修改**如下:

package main

import

("fmt"

"time"

)func

main()

func

test

(ch chan

string

)func

print

(ch chan

string

)}

問題解決,不報錯而且正常輸出

goroot=d:\go #gosetup

gopath=c:\users\wangxihe\go #gosetup

abcdef

process finished with exit code 0

綜上所述,這一切的問題好像都是沒有快取引起的,那麼理論上來說,如果使用有快取的channel是否就可以解決了呢?

附上更改後的**:

package main

import

"fmt"

func

main()

}

執行發現可以輸出結果但還是會報死鎖的錯:

goroot=d:\go #gosetup

gopath=c:\users\wangxihe\go #gosetup

abcdef

fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan receive]:

main.main(

) d:/workspace/go/golearning/ctest.go:10 +0x9f

process finished with exit code 2

分析了一下,發現其實還是同樣的問題,fmt.println(<-ch)又被阻塞了,於是就在讀取之前先把channel關閉,**如下:

package main

import

("fmt"

)func

main()

}

再次執行,問題解決:

goroot=d:\go #gosetup

gopath=c:\users\wangxihe\go #gosetup

abcdef

process finished with exit code 0

GO語言學習之陣列

陣列是乙個由 固定長度的 特定型別元素 組成的序列,乙個陣列可以由乙個或多個元素組成 因為陣列的元素是固定的,所以在go語言當中很少直接使用陣列.一 陣列宣告 陣列宣告語法 var 陣列變數名 元素數量 type 陣列的每個元素都可以通過索引下標來訪問,索引下標的範圍是從0開始,內建函式len 可以...

GO語言學習

sudo apt get install golang但是用ubuntu的庫安裝有幾個不好的地方 因此建議不要使用ubuntu的庫安裝golang環境 golang社群的安裝指導 wget tar c usr local zxf go1.6.2.linux amd64.tar.gz設定環境變數,修改...

Go語言學習

執行 go run go main函式 打包 go build 用於測試編譯包,在專案目錄下生成可執行檔案 有main包 go install 主要用來生成庫和工具。一是編譯包檔案 無main包 將編譯後的包檔案放到 pkg 目錄下 gopath pkg 二是編譯生成可執行檔案 有main包 將可執...