go語言學習-chan使用過程關於close()
阿新 • • 發佈:2019-01-30
chan在go語言中相當於一個檔案操作符,使用完成之後需要使用Close()函式關閉。
下面這段程式碼有兩個chan,ch1是一個chan int型別,ch2是一個chan bool型別,ch1被write()函式寫入10個數,被read()函式讀取,ch2其實是為了防止main所在的goroutine提前退出用的。
我們分別在寫完之後Close()和不Close()看看有什麼不同。
package main
import "fmt"
func read(ch1 chan int,ch2 chan bool){
for{
fmt.Printf("read a int is %d\n" ,<-ch1)
}
ch2 <- true
}
func write(ch chan int){
for i:=0;i<10;i++{
ch <- i
}
//close(ch)
}
func main() {
ch1 := make(chan int)
ch2 := make(chan bool)
go write(ch1)
go read(ch1,ch2)
<-ch2
}
下面是不close()的執行結果:
從執行結果可以看到,當我們將10個數寫完之後,如果不close()ch1,read就會阻塞,程式中所有的協程都被阻塞,ch2無法寫入,也無法讀取,系統這時候檢測到這種錯誤就會報錯。
當我們把close()開啟之後,再執行一遍,看看執行的結果:
我們這次可以看到close之後,read函式在讀完10個數字之後,也不會阻塞會一直讀取到0,ch2也不會因為沒有寫入和讀取導致整個程式報錯。所以我們每次在使用chan完成之後一定要記得關閉,這樣即使我們讀端沒有做讀完處理,程式也不會出錯。
下面是這個例子的正確寫法,我們在讀取chan時可以根據,第二個返回值,判斷寫端是否關閉,如果寫端關閉,則會讀取到false,通過close()和讀取端根據讀chan第二個返回值可以確保管道在讀寫兩端能夠做到寫多少讀多少,程式也能很友好的退出。
package main
import "fmt"
func read(ch1 chan int,ch2 chan bool){
for{
v ,ok:= <- ch1
if ok{
fmt.Printf("read a int is %d\n",v)
}else{
ch2 <- true
}
}
}
func write(ch chan int){
for i:=0;i<10;i++{
ch <- i
}
close(ch)
}
func main() {
ch1 := make(chan int)
ch2 := make(chan bool)
go write(ch1)
go read(ch1,ch2)
<-ch2
}
下面是執行結果: