c语言编程笔录

首页 >   > 笔记大全

笔记大全

golang chan用法

更新时间:2023-09-13

golang chan用法

在Go语言中,chan是goroutine之间通信的重要机制之一。它不仅可以用于多个goroutine之间通信,还可以用于同一个goroutine内部的不同阶段之间通信。

1. 创建和操作chan

创建chan的语法:make(chan element-type)。

    package main

    import "fmt"

    func main() {
      ch1 :=make(chan int) // 创建一个int类型的无缓冲的chan
      ch2 :=make(chan string, 10) // 创建一个string类型,带有10个缓冲的chan
      fmt.Println(ch1)
      fmt.Println(ch2)
    }
  

其中,ch1是无缓冲的chan,也就是说,只有当有goroutine接收ch1时,发送方才能继续发送;而ch2是带有10个缓冲的chan,也就是说,即使当前没有任何goroutine读取ch2,发送方也能够往ch2中发送信息,直到缓冲区被填满。

2. chan的阻塞和非阻塞

通过chan的阻塞和非阻塞,我们可以控制goroutine的执行顺序,以及避免死锁的问题。

    package main

    import (
      "fmt"
      "time"
    )

    func main() {
      ch :=make(chan int, 1)

      go func() {
        time.Sleep(2 * time.Second)
        fmt.Println("goroutine1: sending data")
        ch <- 1
        fmt.Println("goroutine1: data has been sent")
      }()

      select {
        case x :=<-ch:
          fmt.Println("got data:", x)
        case <-time.After(3 * time.Second):
          fmt.Println("timeout")
      }

      fmt.Println("main function exit")
    }
  

在上面的代码中,我们使用了一个带有缓冲的chan,并在另一个goroutine中发送了一个整数1。在main函数中,我们使用了select语句来等待chan的值,如果在3秒内没有从chan中接收到值的话,就会跳出并输出“timeout”这个字符串。如果成功接收到了值,就会输出“got data: 1”。

3. chan的关闭

chan在程序执行完毕后会自动释放,但是我们也可以显式地关闭chan。关闭一个chan后,我们仍然可以从这个chan中读取已经发送的数据,但是不能再向这个chan中发送数据。

    package main

    import "fmt"

    func send(ch chan int, n int) {
      for i :=0; i < n; i++ {
        ch <- i
      }
      close(ch)
    }

    func main() {
      ch :=make(chan int, 3)
      go send(ch, 3)
      for {
        value, ok :=<-ch
        if !ok {
          fmt.Println("chan has been closed")
          break
        }
        fmt.Println("received data:", value)
      }
    }
  

在上面的代码中,我们使用了一个带有3个缓冲的chan,并启动了一个goroutine,在goroutine中向chan发送了三个整数。主函数中通过for循环从chan中读取值,并检查chan是否已被关闭。如果chan已被关闭,则跳出循环并输出“chan has been closed”,否则就输出已接收到的值。

4. 总结

在Go语言中,chan是一种重要的通信机制,可以用于多个goroutine之间通信,也可以用于同一个goroutine内部的不同阶段之间通信。我们可以使用make语法来创建chan,在不同的goroutine中向chan发送和接收数据,以及使用select语句来控制阻塞和非阻塞操作,避免死锁问题的出现。同时,我们也可以显式地关闭chan,但在关闭chan后仍然可以继续从chan中读取已经发送的数据。Go语言中,chan的机制非常强大,它是Go语言并发编程的重要组成部分。