在 Go 语言中,通道(channel)是一个很重要的并发同步机制,可以用来在不同的 goroutine 之间发送和接收数据。
通道实现了一个先进先出(FIFO)的数据结构,所以可以确保数据的接收顺序与发送顺序一致。此外,通道的发送和接收操作都是原子的,这意味着你不需要额外的锁来同步数据访问。
这里有几种不同的方式可以用通道来同步 goroutines:
等待消息:
你可以在一个 goroutine 中发送数据,然后在另一个 goroutine 中接收数据。接收操作会阻塞,直到有数据可以接收。
message := make(chan string)
go func() {
message <- "ping"
}()
msg := <-message
fmt.Println(msg)
在上面的例子中,主 goroutine 会在 msg := <-message 这一行阻塞,直到子 goroutine 向 message 通道发送了数据。
等待通道关闭:
发送者可以关闭通道来表示不会有更多的数据发送了。接收者可以使用 for-range 循环来接收数据,直到通道被关闭。
package main
import "fmt"
func main() {
jobs := make(chan int, 5)
done := make(chan bool)
go func() {
for {
_, more := <-jobs
if more {
fmt.Println("received job")
} else {
fmt.Println("received all jobs")
done <- true
return
}
}
}()
for i := 1; i <= 3; i++ {
jobs <- i
fmt.Println("sent job", i)
}
close(jobs)
fmt.Println("sent all jobs")
<-done
}
在这个例子中,主 goroutine 会在最后的 <-done 这一行阻塞,直到子 goroutine 向 done 通道发送了数据。
使用通道来实现锁:虽然 Go 语言提供了 sync.Mutex 来实现互斥锁,但有时你也可以使用通道来实现类似的效果。例如,你可以创建一个只能存储一个元素的无缓冲通道,然后通过发送和接收操作来实现锁的获取和释放。
mutex := make(chan struct{}, 1)
mutex <- struct{}{} // 获取锁
// critical section
<-mutex // 释放锁
在这个例子中,尝试向 mutex 通道发送数据会阻塞,直到通道中的数据被接收。这就实现了类似于互斥锁的效果。
标签:接收数据,make,goroutine,chan,golang,Synchronization,接收,channel,通道 From: https://www.cnblogs.com/faberbeta/p/17547300.html