开发
软件开发相关知识
Go语言并发模式:Channel、goroutine与select深度应用
Go语言并发模式:Channel、goroutine与select深度应用
摘要
Go语言并发编程深度指南,深入讲解goroutine调度、Channel通信、select多路复用和context上下文管理,通过实际案例展示Go语言高性能并发程序的设计模式。
正文
一、goroutine基础
1.1 创建goroutine
func main() {
go say("world")
say("hello")
}
func say(s string) {
for i := 0; i < 5; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Println(s)
}
}1.2 等待goroutine完成
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
fmt.Printf("goroutine %d done\n", id)
}(i)
}
wg.Wait()二、Channel
2.1 Channel基础
// 创建无缓冲Channel ch := make(chan int) // 创建有缓冲Channel ch := make(chan int, 10) // 发送数据 ch <- 42 // 接收数据 value := <-ch
2.2 单向Channel
// 生产者:只能发送
func producer(out chan<- int) {
for i := 0; i < 10; i++ {
out <- i
}
close(out)
}
// 消费者:只能接收
func consumer(in <-chan int) {
for v := range in {
fmt.Println(v)
}
}三、select多路复用
3.1 select基础
select {
case v := <-ch1:
fmt.Println("从ch1接收:", v)
case v := <-ch2:
fmt.Println("从ch2接收:", v)
case <-time.After(time.Second):
fmt.Println("超时")
}3.2 超时控制
func fetchWithTimeout(url string, timeout time.Duration) (string, error) {
ch := make(chan string)
go func() { ch <- fetch(url) }()
select {
case result := <-ch:
return result, nil
case <-time.After(timeout):
return "", errors.New("timeout")
}
}四、并发模式
4.1 Pipeline模式
func generate(nums ...int) <-chan int {
out := make(chan int)
go func() {
for _, n := range nums {
out <- n
}
close(out)
}()
return out
}
func square(in <-chan int) <-chan int {
out := make(chan int)
go func() {
for n := range in {
out <- n * n
}
close(out)
}()
return out
}