开发

软件开发相关知识

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
}