package main
import (
"fmt"
"sync"
"time"
)
// 数据库连接池结构体
type ConnectionPool struct {
pool chan struct{}
maxConns int
}
// 创建新的数据库连接池
func NewConnectionPool(maxConns int) *ConnectionPool {
return &ConnectionPool{
pool: make(chan struct{}, maxConns),
maxConns: maxConns,
}
}
// 获取一个数据库连接
func (cp *ConnectionPool) GetConnection() {
cp.pool <- struct{}{} // 获取信号量
}
// 释放一个数据库连接
func (cp *ConnectionPool) ReleaseConnection() {
<-cp.pool // 释放信号量
}
func main() {
maxConns := 3
cp := NewConnectionPool(maxConns)
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
cp.GetConnection()
fmt.Printf("Goroutine %d got connection\n", id)
time.Sleep(time.Second) // 模拟数据库操作
fmt.Printf("Goroutine %d released connection\n", id)
cp.ReleaseConnection()
}(i)
}
wg.Wait()
}
- 信号量初始化:
pool
是一个带缓冲的通道,其缓冲大小 maxConns
就是信号量的数量,以此来限制同时能获取的连接数。
- 获取连接:
GetConnection
方法通过向 pool
通道发送一个空结构体来获取信号量,若通道已满(即达到最大连接数),则会阻塞,直到有连接被释放。
- 释放连接:
ReleaseConnection
方法通过从 pool
通道接收一个空结构体来释放信号量,使得其他等待的 goroutine 可以获取连接。