笔记 - goroutine、channel详解

Golang
315
0
0
2022-10-11
标签   Golang基础
  • goroutine
  • channel通道 (goroutine通信)
package main
import "fmt"
func main() {

  var ch1 chan bool
  ch1 = make(chan bool)

  go func() {
      for i := 0; i < 10; i++ {
          fmt.Println("子goroutine:", i)
      }
      ch1 <- true

      fmt.Println("over")
  }()

  // 读数据是阻塞的
  <-ch1

  fmt.Println("main over")
}
  • 关闭通道及范围循环
package main
import (
  "fmt" 
  "time"
)
func main() {

  ch1 := make(chan int)

  go sendData(ch1)

  // 第一种方式读取通道 
  for {

      time.Sleep(1 * time.Second)

      v, ok := <-ch1

      if !ok {
          fmt.Println("读完了 over")
          break
      }
      fmt.Println("读取数据", v)
  }

  // 第二种方式读取通道 
  for v := range ch1 { // v <- ch1
      fmt.Println("数据:", v)
  }

  fmt.Println("main.... over...")
}
func sendData(ch1 chan int) {
  for i := 0; i < 10; i++ {
      time.Sleep(1 * time.Second)
      ch1 <- i
  }
  // 关闭通道 
  close(ch1)
}
  • 缓存通道(可理解为一个定长的队列)
package main
import (
  "fmt" 
  "strconv"
)
func main() {
  /**
  * 非缓冲 make(chan T)
  * 缓冲 make(chan T, capacity)
  * 发送: 缓冲区的数据满了,才会阻塞
  * 接受: 缓冲区的数据空了,才会阻塞
   */

  ch1 := make(chan int)
  fmt.Println(len(ch1), cap(ch1))
  ch1 <- 100

  ch2 := make(chan int, 5)
  fmt.Println(len(ch2), cap(ch2))

  ch2 <- 100
  fmt.Println(len(ch2), cap(ch2))

  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 <- "data" + strconv.Itoa(i)

      fmt.Printf("子gorountine第%d个数据", i)
  }
  close(ch)
}
  • 定向通道
package main
import "fmt"
func main() {
  /**
   双向通道:
       chan T
            chan <- data, 发送数据,写出
            data <- chan, 获取数据,读取

   单向通道: 定向
       chan <- T, 只支持写
       <-chan T, 只支持读
  */

  ch1 := make(chan string)
  ch2 := make(chan<- int) // 单项,只能写,不能读
  ch3 := make(<-chan int) // 单项。只能读,不能写 
  go sendData(ch1)
  data := <-ch1 // 读取
  fmt.Println("子roroutine数据", data)
  ch1 <- "我是main"
}
func sendData(ch1 chan string) {
  ch1 <- "我是子"

  data := <-ch1
  fmt.Println("main goroutine传来:", data)
}