golang面試題:對未初始化的的chan進行讀寫,會怎麼樣?爲何?

問題

未初始化的的 chan 進行讀寫,會怎麼樣?爲何?golang

怎麼答

讀寫未初始化chan 都會阻塞web

舉例

1. 寫未初始化的 chan
package main
// 寫未初始化的chan func main() {  var c chan int  c <- 1 } 複製代碼
// 輸出結果
fatal error: all goroutines are asleep - deadlock!  goroutine 1 [chan send (nil chan)]: main.main()  /Users/admin18/go/src/code.byted.org/linzhaolun/repos/main.go:6 +0x36 複製代碼

注意這個 chan send (nil chan),待會會提到。面試

2. 寫讀未初始化的 chan
package main
import "fmt" // 讀未初始化的chan func main() {  var c chan int  num, ok := <-c  fmt.Printf("讀chan的協程結束, num=%v, ok=%v\n", num, ok) } 複製代碼
// 輸出結果
fatal error: all goroutines are asleep - deadlock!  goroutine 1 [chan receive (nil chan)]: main.main()  /Users/admin18/go/src/code.byted.org/linzhaolun/repos/main.go:6 +0x46 複製代碼

注意這個 chan receive (nil chan),待會也會提到。json

多問一句

關於 chan 的面試題很是多,這個是比較常見的其中一個。但多問一句:爲何對未初始化的 chan 就會阻塞呢?數組

1. 對於寫的狀況編輯器

//在 src/runtime/chan.go中
func chansend(c *hchan, ep unsafe.Pointer, block bool, callerpc uintptr) bool {  if c == nil {  // 不能阻塞,直接返回 false,表示未發送成功  if !block {  return false  }  gopark(nil, nil, waitReasonChanSendNilChan, traceEvGoStop, 2)  throw("unreachable")  }  // 省略其餘邏輯 } 複製代碼
  • 未初始化的 chan 此時是等於 nil,當它不能阻塞的狀況下,直接返回 false,表示寫 chan 失敗
  • chan 能阻塞的狀況下,則直接阻塞 gopark(nil, nil, waitReasonChanSendNilChan, traceEvGoStop, 2), 而後調用 throw(s string) 拋出錯誤,其中 waitReasonChanSendNilChan 就是剛剛提到的報錯 "chan send (nil chan)"

2. 對於讀的狀況學習

//在 src/runtime/chan.go中
func chanrecv(c *hchan, ep unsafe.Pointer, block bool) (selected, received bool) {  //省略邏輯...  if c == nil {  if !block {  return  }  gopark(nil, nil, waitReasonChanReceiveNilChan, traceEvGoStop, 2)  throw("unreachable")  }  //省略邏輯... } 複製代碼
  • 未初始化的 chan 此時是等於 nil,當它不能阻塞的狀況下,直接返回 false,表示讀 chan 失敗
  • chan 能阻塞的狀況下,則直接阻塞 gopark(nil, nil, waitReasonChanReceiveNilChan, traceEvGoStop, 2), 而後調用 throw(s string) 拋出錯誤,其中 waitReasonChanReceiveNilChan 就是剛剛提到的報錯 "chan receive (nil chan)"

文章推薦:

若是你想天天學習一個知識點?

本文使用 mdnice 排版ui

相關文章
相關標籤/搜索