笔记 - goroutine、channel详解

  • 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)
    }
本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!