MST

星途 面试题库

面试题:Go生成器与sync包中的并发原语协作应用场景

在Go语言中,sync包提供了诸如Mutex、WaitGroup等并发原语。请阐述生成器与这些原语协作的典型应用场景,并详细说明如何使用它们来解决实际并发编程中的问题,比如资源竞争和同步问题。
19.4万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

生成器与sync包原语协作的典型应用场景

  1. 资源共享与竞争控制:当多个协程需要访问共享资源(如数据库连接池、缓存等)时,可能会出现资源竞争问题。生成器可以产生对这些共享资源的操作请求,而Mutex可以用来保护共享资源,确保同一时间只有一个协程能访问它。
  2. 协程同步:在一些场景下,需要等待一组协程全部完成任务后再进行下一步操作。例如,一个生成器生成任务,多个协程并行处理这些任务,WaitGroup可以用来同步这些协程,确保所有任务都完成后程序继续执行。

使用示例

  1. 使用Mutex解决资源竞争问题
package main

import (
    "fmt"
    "sync"
)

// 假设这是一个共享资源
var sharedResource int
var mu sync.Mutex

// 生成器函数,生成操作共享资源的任务
func generator(wg *sync.WaitGroup) {
    for i := 0; i < 10; i++ {
        go func(id int) {
            defer wg.Done()
            // 加锁保护共享资源
            mu.Lock()
            sharedResource += id
            fmt.Printf("协程 %d 修改共享资源为 %d\n", id, sharedResource)
            mu.Unlock()
        }(i)
    }
}

func main() {
    var wg sync.WaitGroup
    wg.Add(10)
    generator(&wg)
    wg.Wait()
    fmt.Printf("最终共享资源的值为: %d\n", sharedResource)
}

在上述代码中,generator函数创建多个协程对共享资源sharedResource进行操作。MutexLockUnlock方法确保同一时间只有一个协程能够修改sharedResource,从而避免资源竞争。

  1. 使用WaitGroup进行协程同步
package main

import (
    "fmt"
    "sync"
)

// 生成器函数,生成需要处理的任务
func generator(wg *sync.WaitGroup) <-chan int {
    resultChan := make(chan int)
    go func() {
        for i := 0; i < 5; i++ {
            wg.Add(1)
            go func(id int) {
                defer wg.Done()
                result := id * id
                resultChan <- result
            }(i)
        }
        close(resultChan)
    }()
    return resultChan
}

func main() {
    var wg sync.WaitGroup
    resultChan := generator(&wg)
    go func() {
        wg.Wait()
        close(resultChan)
    }()
    for result := range resultChan {
        fmt.Printf("收到结果: %d\n", result)
    }
}

在这个示例中,generator函数创建多个协程处理任务,并使用WaitGroup来同步这些协程。主协程通过for... range从通道resultChan中接收处理结果,确保在所有协程完成任务后才结束程序。