天天看点

go语言基础 通道 channel

1.通道的概念:

Channel,通道,专门用于goroutine之间传递消息

也是一种引用类型的数据:可以作为参数,也可以作为返回值

语法:

1.创建:make(chan T)

2.使用:

发送数据:写

chan <- data

接收数据:读

data := <- chan

通道的阻塞:

不带缓存:发送和接收都是阻塞的。

发送是阻塞的,直到有另一个goroutine读取数据解除阻塞。

类似的,接收也是阻塞的,直到另一个goroutine写出数据解除阻塞

2.关闭通道:发送方关闭通道,用于通知接收方已经没有数据了。

close(chan),

v,ok <- chan

关闭通道后,其他的goroutine访问通道获取数据时候,得到是零值和false

A:死循环,可以有结束的条件。

for{

v ,ok := <- chan

if ok== false{

//通道已经关闭。。

break

}

}

B:for range chan

循环从通道中获取数据,直到通道关闭。

for v := range chan{

....v

}

package main

import "fmt"

func main()  {
   /*
   Channel,通道,
      1.用于goroutine,传递消息的。
      2.通道,每个都有相关联的数据类型,
         nil chan,不能使用,类似于nil map,不能直接存储键值对
      3.使用通道传递数据:<-
         chan <- data,发送数据到通道。向通道中写数据
         data <- chan,从通道中获取数据。从通道中读数据
      4.阻塞:
         发送数据:chan <- data,阻塞的,直到另一条goroutine,读取数据来解除阻塞
         读取数据:data <- chan,也是阻塞的。直到另一条goroutine,写出数据解除阻塞。
      5.本身channel就是同步的,意味着同一时间,只能有一条goroutine来操作。
    */
    var ch1 chan bool //声明,没有创建
   fmt.Println(ch1) //<nil>
   fmt.Printf("%T\n", ch1) //chan bool
   ch1 = make(chan bool) //0xc042036060,是引用类型的数据
   fmt.Println(ch1)


   go func() {
      for i:=0; i<10; i++ {
         fmt.Println("子goroutine中,i:",i)
      }
      // 循环结束后,向通道中写数据,表示要结束了。。
      ch1 <- true

      fmt.Println("结束。。")


   }()


   data:=<- ch1 // 从ch1通道中读取数据
   fmt.Println("data-->", data)
   fmt.Println("main。。over。。。。")
}