Go語言中的有緩沖channel和無緩沖channel區別
結論
ch1:=make(chan int)// 無緩沖
ch2:=make(chan int,1)// 有緩沖
無緩沖: 當向ch1中存值后需要其他協程取值,否則一直阻塞
有緩沖: 不會阻塞,因為緩沖大小是1,只有當放第二個值的時候,第一個還沒被人拿走,才會阻塞。
測試程序
測試1,聲明無緩沖channel
func Test_1(t *testing.T) {
// 無緩沖
ch := make(chan int)
// fatal error: all goroutines are asleep - deadlock! 協程阻塞,需要另一個協程取走channel中的值
ch <- 1
}
運行結果:
=== RUN Test_1
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan receive]:
testing.(*T).Run(0xc0000c0100, 0x55bb8e, 0x6, 0x566b20, 0x47e55d)
D:/Go/src/testing/testing.go:961 +0x37e
testing.runTests.func1(0xc0000c0000)
D:/Go/src/testing/testing.go:1202 +0x7f
testing.tRunner(0xc0000c0000, 0xc00008fdc0)
D:/Go/src/testing/testing.go:909 +0xd0
testing.runTests(0xc000060460, 0x654300, 0x4, 0x4, 0x0)
D:/Go/src/testing/testing.go:1200 +0x2ae
testing.(*M).Run(0xc0000b6000, 0x0)
D:/Go/src/testing/testing.go:1117 +0x17d
main.main()
_testmain.go:50 +0x13c
goroutine 19 [chan send]:
test/review.Test_1(0xc0000c0100)
E:/Go/src/test/review/main_test.go:64 +0x57
testing.tRunner(0xc0000c0100, 0x566b20)
D:/Go/src/testing/testing.go:909 +0xd0
created by testing.(*T).Run
D:/Go/src/testing/testing.go:960 +0x357
Process finished with exit code 1
測試2,開啟協程取值
func Test_2(t *testing.T) {
// 無緩沖
ch := make(chan int)
go func() {
// 睡眠1秒,等待主協程在channel寫入值
time.Sleep(time.Second * 1)
fmt.Println("開始取值。。。")
<-ch
}()
fmt.Println("開始存值。。。")
ch <- 1
time.Sleep(time.Second*5)
fmt.Println("結束。。。")
}
運行結果:
=== RUN Test_2
開始存值。。。
開始取值。。。
結束。。。
--- PASS: Test_2 (6.00s)
PASS
Process finished with exit code 0
測試3,聲明有緩沖channel
func Test_3(t *testing.T) {
// 有緩沖
ch1 := make(chan int, 1)
// 緩沖大小為1 即是當channel中有一個值時不會被阻塞,當再塞入一個時前一個沒被其他協程取走才會阻塞
ch1 <- 2
// 此時主協程也可取出值
fmt.Println(<-ch1)
}
運行結果:
=== RUN Test_3
2
--- PASS: Test_3 (0.00s)
PASS
Process finished with exit code 0
測試4,存入超過緩沖數量的值
func Test_4(t *testing.T) {
// 有緩沖
ch1 := make(chan int, 1)
// 緩沖大小為1 即是當channel中有一個值時不會被阻塞,當再塞入一個時前一個沒被其他攜程取走才會阻塞
ch1 <- 1
// fatal error: all goroutines are asleep - deadlock!
ch1 <- 2
}
測試結果:
=== RUN Test_4
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan receive]:
testing.(*T).Run(0xc0000a8100, 0x55bba0, 0x6, 0x566b40, 0x47e501)
D:/Go/src/testing/testing.go:961 +0x37e
testing.runTests.func1(0xc0000a8000)
D:/Go/src/testing/testing.go:1202 +0x7f
testing.tRunner(0xc0000a8000, 0xc000081dc0)
D:/Go/src/testing/testing.go:909 +0xd0
testing.runTests(0xc0000044c0, 0x654300, 0x4, 0x4, 0x0)
D:/Go/src/testing/testing.go:1200 +0x2ae
testing.(*M).Run(0xc00009e000, 0x0)
D:/Go/src/testing/testing.go:1117 +0x17d
main.main()
_testmain.go:50 +0x13c
goroutine 6 [chan send]:
test/review.Test_4(0xc0000a8100)
E:/Go/src/test/review/main_test.go:97 +0x76
testing.tRunner(0xc0000a8100, 0x566b40)
D:/Go/src/testing/testing.go:909 +0xd0
created by testing.(*T).Run
D:/Go/src/testing/testing.go:960 +0x357
Process finished with exit code 1
