文章目录
-
- [无缓冲的 channel](#无缓冲的 channel)
- [有缓冲的 channel](#有缓冲的 channel)
- [创建一个无缓冲的 channel 并在 select 语句中使用](#创建一个无缓冲的 channel 并在 select 语句中使用)
- [goroutine 和 channel 生产者-消费者模型](#goroutine 和 channel 生产者-消费者模型)
无缓冲的 channel
无缓冲的 channel 在发送和接收操作时会阻塞,直到另一端准备好。
go
ch := make(chan int)
有缓冲的 channel
带缓冲的 channel 在缓冲区未满时,发送操作不会阻塞;在缓冲区有数据时,接收操作不会阻塞。
go
ch := make(chan int, 10) // 缓冲区大小为 10
创建一个无缓冲的 channel 并在 select 语句中使用
可以在 select 语句中使用 channel。
go
func main() {
ch := make(chan int)
go func() {
ch <- 42
}()
select {
case val := <-ch:
fmt.Println(val)
}
}
- 使用 make 函数创建 channel。
- 可以创建无缓冲或带缓冲的 channel。
- 可以通过方向操作符 <- 来限制 channel 的发送或接收能力。
- channel 常用于 goroutine 之间的通信和同步。
goroutine 和 channel 生产者-消费者模型
不论 1:n 还是 n:1 或是 n:m,都可以使用 sync.WaitGroup
下面这种模型来操作。
go
package main
import (
"fmt"
"sync"
"time"
)
func producer(id int, jobs chan<- int, wg *sync.WaitGroup) {
defer wg.Done()
for i := 0; i < 5; i++ {
time.Sleep(time.Millisecond * 100)
jobs <- i
fmt.Printf("Producer %d produced %d\n", id, i)
}
}
func consumer(id int, jobs <-chan int, wg *sync.WaitGroup) {
defer wg.Done()
for job := range jobs {
time.Sleep(time.Millisecond * 500)
fmt.Printf("Consumer %d consumed %d\n", id, job)
}
}
func main() {
jobs := make(chan int, 10)
var wg sync.WaitGroup
const numProducers = 3
const numConsumers = 2
wg.Add(numProducers)
for i := 0; i < numProducers; i++ {
go producer(i, jobs, &wg)
}
wg.Add(numConsumers)
for i := 0; i < numConsumers; i++ {
go consumer(i, jobs, &wg)
}
wg.Wait()
close(jobs)
}