1.非缓冲通道:发送和接收到一个未缓冲的通道是阻塞的;一次发送操作对应一次接收操作;对于一个goroutine来讲,它的一次发送,在另一个goroutine接受之前都是阻塞的,同样的,对于接收来讲,在另一个goroutine发送之前,它也是阻塞的
2.缓冲通道:指一个通道,带有一个缓冲区。发送到一个缓冲通道只有在缓冲区满时才被阻塞。类似地,从缓冲通道接收的信息只有在缓冲区为空时才会被阻塞
- 语法:ch := make(chan type, capactity);capactity应该大于零,以便通道具有缓冲区;无缓冲通道的容量为0,因此之前创建通道时省略了容量参数
func main() {
ch3 := make(chan string, 4)
go sendData(ch3)
for{
v, ok := <-ch3
if !ok{
fmt.Println("读完了。。。", ok)
break
}
fmt.Println("读取的数据是:", 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)
}
3.定向通道
- 双向通道:一个goroutine可以向通道发送数据,也可以接收数据
双向通道:
chan
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//因为阻塞,所以会等待子goroutine的 通道done发送数据
fmt.Println("main...over...")
//time.Sleep(1)
}
func sendData(ch1 chan string, done chan bool) {
ch1 <- "我是lzc" //发送
data := <- ch1 //读取数据
fmt.Println("main goroutine传来的数据:", data)
done <- true
}
单向:单向
chan <- T, 只支持写
<- chan T, 只读
ch2 := make(chan <- int)//单向,只能写,不能读
ch2 <- 100
data := <- ch2
invalid operation: <-ch2 (receive from send-only type chan<- int)
ch3 := make(<- chan int)//单向,只能读,不能写
ch3 <- 100
invalid operation: ch3 <- 100 (send to receive-only type <-chan int)