MST

星途 面试题库

面试题:Go中如何使用信号量实现简单的并发限制

请描述在Go语言中,使用信号量实现并发限制的基本原理,并给出一个简单示例代码,限制并发数为5,模拟多个任务同时执行。
24.8万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

基本原理

在Go语言中,信号量(Semaphore)是一种用于控制并发访问资源的机制。其基本原理是通过维护一个计数器,该计数器表示当前可用的资源数量。当一个任务想要访问受信号量保护的资源时,它需要先获取信号量(即计数器减1),如果计数器的值大于0,则获取成功,任务可以继续执行;如果计数器的值为0,则获取失败,任务需要等待,直到有其他任务释放信号量(即计数器加1)。

示例代码

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("Task %d is running\n", id)
            time.Sleep(1 * time.Second)
            fmt.Printf("Task %d is done\n", id)
        }(i)
    }

    wg.Wait()
}

在上述代码中:

  1. semaphore 是一个有缓冲的通道,其缓冲区大小为5,即信号量的初始值为5,表示允许同时执行5个任务。
  2. 在启动每个任务前,向 semaphore 通道发送一个空结构体,这相当于获取信号量,如果通道已满(即信号量为0),则会阻塞,直到有任务释放信号量。
  3. 每个任务执行完毕后,从 semaphore 通道接收一个空结构体,这相当于释放信号量,让其他等待的任务有机会获取信号量并执行。
  4. sync.WaitGroup 用于等待所有任务完成。