在 Go语言并发编程 中,合理控制并发资源的访问是保证程序稳定性和性能的关键。其中,信号量(Semaphore)是一种经典的同步原语,特别适用于限制同时访问某一资源的协程(goroutine)数量。本文将带你从零开始,用 Go 语言实现一个计数信号量,并解释其工作原理,即使是 Go 并发编程的小白也能轻松掌握。

信号量最早由 Dijkstra 提出,用于解决多进程/线程对共享资源的竞争问题。它本质上是一个整型变量,配合两个原子操作:P()(申请资源)和 V()(释放资源)。
在 计数信号量 中,这个整型值表示当前可用的“许可证”数量。当值大于0时,协程可以获取一个许可证并继续执行;当值为0时,后续协程必须等待,直到有其他协程释放许可证。
在实际开发中,我们常遇到以下场景:
虽然 Go 提供了 channel、sync.WaitGroup、mutex 等工具,但它们并不直接支持“最多 N 个协程同时运行”的语义。而信号量正好填补了这一空白。
Go 标准库并没有直接提供信号量类型,但我们可以通过 chan struct{} 轻松实现一个高效的计数信号量。
核心思想:创建一个容量为 N 的 channel,每次获取信号量就向 channel 发送一个空结构体(占用一个槽位),释放时从 channel 接收(释放一个槽位)。由于 channel 容量有限,当满时发送操作会阻塞,从而实现限流效果。
package mainimport ( "fmt" "sync" "time")// Semaphore 计数信号量type Semaphore struct { ch chan struct{}}// NewSemaphore 创建一个新的信号量,maxConcurrency 表示最大并发数func NewSemaphore(maxConcurrency int) *Semaphore { return &Semaphore{ ch: make(chan struct{}, maxConcurrency), }}// Acquire 获取一个许可证(阻塞直到可用)func (s *Semaphore) Acquire() { s.ch <- struct{}{}}// Release 释放一个许可证func (s *Semaphore) Release() { <-s.ch}func main() { sem := NewSemaphore(3) // 最多允许3个 goroutine 同时运行 var wg sync.WaitGroup for i := 0; i < 10; i++ { wg.Add(1) go func(id int) { defer wg.Done() sem.Acquire() // 获取许可证 fmt.Printf("Goroutine %d 开始执行\n", id) time.Sleep(2 * time.Second) // 模拟耗时操作 fmt.Printf("Goroutine %d 执行完毕\n", id) sem.Release() // 释放许可证 }(i) } wg.Wait() fmt.Println("所有任务完成!")}NewSemaphore(3) 创建了一个最多允许3个并发的信号量。Acquire(),如果已有3个在运行,则第4个会阻塞,直到某个 goroutine 调用 Release()。sync.WaitGroup 等待所有任务完成。运行这段代码,你会发现输出中最多只有3个 goroutine 同时处于“执行中”状态,完美实现了并发控制。
在某些场景下,我们不希望 goroutine 无限期等待。可以通过 select + time.After 实现带超时的 Acquire:
func (s *Semaphore) AcquireWithTimeout(timeout time.Duration) bool { select { case s.ch <- struct{}{}: return true // 成功获取 case <-time.After(timeout): return false // 超时 }}这样,调用方可以根据返回值决定是否重试或放弃。
通过本文,你已经掌握了如何在 Go语言并发编程 中实现和使用 计数信号量。这种模式非常适合用于 Go并发控制 场景,如限流、资源池管理等。虽然 Go 没有内置信号量,但借助 channel 的强大能力,我们可以轻松构建高效、安全的并发控制机制。
记住:合理使用信号量,不仅能提升系统稳定性,还能避免资源耗尽。现在,就去你的项目中试试吧!
—— 本文关键词:Go语言并发编程、信号量实现、计数信号量、Go并发控制 ——
本文由主机测评网于2025-12-21发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://www.vpshk.cn/20251210970.html