Go非缓冲/缓冲/双向/单向通道
1. 非缓冲和缓冲
package main import ( "fmt" "strconv" ) func main() { /* 非缓冲通道:make(chan T) 一次发送,一次接收,都是阻塞的 缓冲通道:make(chan T , capacity) 发送:缓冲区的数据满了,才会阻塞 接收:缓冲区的数据空了,才会阻塞 */ ch1 := make(chan int) //非缓冲通道 fmt.Println(len(ch1), cap(ch1)) //0 0 //ch1 <- 100 //阻塞式的,需要有其他的goroutine解除阻塞,否则deadlock ch2 := make(chan int, 5) //缓冲通道,缓冲区大小是5 fmt.Println(len(ch2), cap(ch2)) //0 5 ch2 <- 100 fmt.Println(len(ch2), cap(ch2)) //1 5 ch2 <- 200 ch2 <- 300 ch2 <- 400 ch2 <- 500 fmt.Println(len(ch2), cap(ch2)) //5 5 //ch2 <- 600 //没有接触阻塞,满了 ch3 := make(chan string, 4) go sendData(ch3) for { v, ok := <-ch3 if !ok { fmt.Println("读完了。。", ok) break } fmt.Println("\t读取的数据是:", v) } fmt.Println("main。。over。。。。") } func sendData(ch chan string) { for i := 0; i < 10; i++ { ch <- "数据" + strconv.Itoa(i) fmt.Printf("子goroutine中写出第 %d 个数据\n", i) } close(ch) }
2. 双向通道
package main import "fmt" func main() { /* 双向: chan T chan <- data,发送数据,写出 data <- chan,获取数据,读取 单向:定向 chan <- T,只支持写 <- chan T,只读 */ ch1 := make(chan string) done := make(chan bool) go sendData(ch1,done) data := <- ch1 //读取 fmt.Println("子goroutine传来:",data) ch1 <- "我是main" //发送 <- done fmt.Println("main..over...") } func sendData(ch1 chan string,done chan bool){ ch1 <- "我是" //发送 data := <- ch1 //读取 fmt.Println("main goroutine传来:",data) done <- true }
3. 单向通道
package main import "fmt" func main() { /* 单向:定向 chan <- T,只支持写 <- chan T,只读 定向通道: 双向:-->函数:只读,只写 */ ch1 := make(chan int) //双向,读,写 //ch2 := make(chan<- int) //单向,只能写,不能读 //ch3 := make(<-chan int) //单向,只能读,不能写 // //ch1 <- 100 //data := <-ch1 //ch2 <- 1000 //data := <-ch2 //invalid operation: <-ch2 (receive from send-only type chan<- int) //data := <-ch3 //ch3 <- 2000 //invalid operation: ch3 <- 2000 (send to receive-only type <-chan int) go fun1(ch1) //可读,可写 //go fun1(ch2) //只写 data := <-ch1 fmt.Println("fun1函数中写出的数据是:", data) go fun2(ch1) //fun2(ch3) ch1 <- 200 fmt.Println("main..over...") } //该函数,只能操作只写的通道 func fun1(ch chan<- int) { //在函数内部,对于ch1通道,只能写数据,不能读取数据 ch <- 100 fmt.Println("fun1函数结束。。。") } //该函数,只能操作只读的通道 func fun2(ch <-chan int) { data := <-ch fmt.Println("fun2函数,从ch中读取的数据是:", data) }