MST

星途 面试题库

面试题:Go中如何使用信号量控制并发访问

请简述在Go语言中使用信号量来控制并发访问的基本思路,并给出一个简单示例代码,该示例要限制同时运行的协程数量为5。
34.9万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

基本思路

在Go语言中,信号量可以通过 sync.WaitGroup 和通道(channel)来模拟实现。基本思路是利用一个带缓冲的通道来表示可用的资源数量,每个协程在开始时尝试从通道获取一个信号(如果通道已满则阻塞等待),完成任务后将信号放回通道,以此来控制同时运行的协程数量。

示例代码

package main

import (
    "fmt"
    "sync"
    "time"
)

func main() {
    var wg sync.WaitGroup
    semaphore := make(chan struct{}, 5)

    for i := 0; i < 10; i++ {
        wg.Add(1)
        semaphore <- struct{}{}
        go func(id int) {
            defer func() {
                <-semaphore
                wg.Done()
            }()
            fmt.Printf("协程 %d 开始执行\n", id)
            time.Sleep(1 * time.Second)
            fmt.Printf("协程 %d 执行结束\n", id)
        }(i)
    }

    wg.Wait()
}

在上述代码中:

  1. 定义了一个带缓冲为5的通道 semaphore 作为信号量。
  2. 在启动每个协程前,向 semaphore 通道发送一个空结构体,若通道已满则会阻塞,从而限制并发数量。
  3. 在协程结束时,从 semaphore 通道接收一个空结构体,将信号量归还,使得其他协程可以获取信号量继续执行。
  4. 使用 sync.WaitGroup 来等待所有协程执行完毕。