小白一枚,最近在入門學習golang,在學到channel時,發現總會遇到死鎖的問題:
fatal error: all goroutines are asleep - deadlock!
所以,當我們寫的程式生產和消費的數量不對等時,便會發生阻塞造成死鎖
生產者阻塞:
生產4條訊息,只消費3條
package main
import (
"fmt"
"sync"
)var wg sync.waitgroup
func producer(ch chan<- int)
}func consumer(ch <-chan int)
}func main()
goroot=/usr/local/go #gosetup
gopath=/users/why/desktop/go #gosetup
/usr/local/go/bin/go build -o /private/var/folders/_s/jfrm6_712w58sytpc753pmr40000gn/t/___go_build_why_go /users/why/desktop/go/why.go #gosetup
/private/var/folders/_s/jfrm6_712w58sytpc753pmr40000gn/t/___go_build_why_go #gosetup
result: 1
result: 2
result: 3
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [semacquire]:
sync.runtime_semacquire(0x1195ae8)
/usr/local/go/src/runtime/sema.go:56 +0x42
sync.(*waitgroup).wait(0x1195ae0)
/usr/local/go/src/sync/waitgroup.go:130 +0x64
main.main()
/users/why/desktop/go/why.go:30 +0xb1
goroutine 18 [chan send]:
main.producer(0xc000070060)
/users/why/desktop/go/why.go:12 +0x7c
created by main.main
/users/why/desktop/go/why.go:27 +0x7f
process finished with exit code 2
可以發現錯誤出現在chan send
消費者阻塞:
消費4條訊息,只生產3條
package main
import (
"fmt"
"sync"
)var wg sync.waitgroup
func producer(ch chan<- int)
}func consumer(ch <-chan int)
}func main()
goroot=/usr/local/go #gosetup
gopath=/users/why/desktop/go #gosetup
/usr/local/go/bin/go build -o /private/var/folders/_s/jfrm6_712w58sytpc753pmr40000gn/t/___go_build_why_go /users/why/desktop/go/why.go #gosetup
/private/var/folders/_s/jfrm6_712w58sytpc753pmr40000gn/t/___go_build_why_go #gosetup
result: 1
result: 2
result: 3
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [semacquire]:
sync.runtime_semacquire(0x1195ae8)
/usr/local/go/src/runtime/sema.go:56 +0x42
sync.(*waitgroup).wait(0x1195ae0)
/usr/local/go/src/sync/waitgroup.go:130 +0x64
main.main()
/users/why/desktop/go/why.go:30 +0xb1
goroutine 7 [chan receive]:
main.consumer(0xc000070060)
/users/why/desktop/go/why.go:19 +0x9b
created by main.main
/users/why/desktop/go/why.go:28 +0xa1
process finished with exit code 2
可以發現錯誤出現在chan receive
實際應用場景,我們並不能預先知道生產者和消費者的準確數量,該如何保證不發生阻塞造成死鎖呢?
golang中提供了乙個函式:close(ch),該函式是用來關閉通道的,我們在傳送完需要傳送的資料後,就用close將通道關閉,訊息接收端接收可以借用 for range 語句進行多個元素的接收操作
舉個例子幫助理解:北京的早高峰是非常嚇人的,尤其是著名的天通苑,每天地鐵都會進行限流,工作人員限流(用close關閉通道)後,人就不再進入地鐵站(傳送的協程停止傳送訊息),而進入地鐵站的人都按照進站(訊息產生)的順序依次進行安檢(通過for range依次獲取訊息),進入地鐵站乘坐地鐵(消費者處理)。
所以最終**如下:
package main
import (
"fmt"
"sync"
)var wg sync.waitgroup
func producer(ch chan<- int)
close(ch)
}func consumer(ch <-chan int)
}func main()
gopath=/users/why/desktop/go #gosetup
/usr/local/go/bin/go build -o /private/var/folders/_s/jfrm6_712w58sytpc753pmr40000gn/t/___go_build_why_go /users/why/desktop/go/why.go #gosetup
/private/var/folders/_s/jfrm6_712w58sytpc753pmr40000gn/t/___go_build_why_go #gosetup12
345process finished with exit code 0
關於golang面向介面
傳統語言的繼承多型由go語言的介面完成 所以go語言的介面比較靈活 go語言介面由使用者定義 傳統語言由實現者定義 先來乙個簡單的介面示例 package mock 介面方法專用包 type retriever struct func r retriever get url string strin...
Golang 在Golang中使用json
由於要開發乙個小型的web應用,而web應用大部分都會使用json作為資料傳輸的格式,所以有了這篇文章。包引用import 用於存放資料的結構體type mydata struct這裡需要注意的就是後面單引號中的內容。json item 這個的作用,就是name欄位在從結構體例項編碼到json資料格...
Golang 關於通道 Chan 詳解
首先我們來看執行緒,在golang裡面也叫goroutine 下面我們先來看乙個例子吧 import fmt funcmain 在golang裡面,使用go這個關鍵字,後面再跟上乙個函式就可以建立乙個執行緒。後面的這個函式可以是已經寫好的函式,也可以是乙個匿名函式 funcmain i fmt.pr...