golang chan用法
更新时间:2023-09-13golang 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语言并发编程的重要组成部分。