设计思路
- 使用互斥锁(Mutex):对于共享的复杂数据结构,使用
sync.Mutex
来保护对其的读写操作,防止资源竞争。
- 数据库连接池:为了高效管理数据库连接,使用连接池,避免每次请求都创建新的连接,减少资源开销。
- 通道(Channel):利用通道来进行不同 goroutine 之间的通信,确保数据传递的有序性和安全性。
- 死锁预防:通过合理的资源获取顺序和避免循环依赖来预防死锁。在获取多个资源时,始终按照相同的顺序获取。
关键部分代码框架
package main
import (
"database/sql"
"fmt"
"sync"
_ "github.com/go-sql-driver/mysql" // 假设使用 MySQL 数据库
)
// 定义复杂的数据结构
type ComplexData struct {
InnerStruct1 InnerStruct1
InnerStruct2 InnerStruct2
// 假设的通道用于模块间通信
CommunicationChannel chan string
mu sync.Mutex
}
type InnerStruct1 struct {
// 具体字段
Field1 string
}
type InnerStruct2 struct {
// 具体字段
Field2 int
}
// 数据库连接池
var db *sql.DB
func init() {
var err error
db, err = sql.Open("mysql", "user:password@tcp(127.0.0.1:3306)/database_name")
if err != nil {
panic(err.Error())
}
// 测试连接
err = db.Ping()
if err != nil {
panic(err.Error())
}
}
// 处理请求的函数
func handleRequest(data *ComplexData, requestID int) {
data.mu.Lock()
defer data.mu.Unlock()
// 操作共享数据结构
fmt.Printf("Handling request %d on shared data\n", requestID)
// 从数据库连接池获取连接
conn, err := db.Conn(nil)
if err != nil {
fmt.Printf("Error getting connection: %v\n", err)
return
}
defer conn.Close()
// 执行数据库操作
rows, err := conn.Query("SELECT * FROM some_table")
if err != nil {
fmt.Printf("Error querying database: %v\n", err)
return
}
defer rows.Close()
// 处理数据库结果
for rows.Next() {
// 处理逻辑
}
}
func main() {
var wg sync.WaitGroup
sharedData := ComplexData{
CommunicationChannel: make(chan string),
}
// 模拟多个请求
for i := 0; i < 10; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
handleRequest(&sharedData, id)
}(i)
}
wg.Wait()
close(sharedData.CommunicationChannel)
}
代码说明
- ComplexData 结构体:包含了内部子结构体以及一个通道,同时添加了
sync.Mutex
用于保护对该结构体的操作。
- 数据库连接池:通过
sql.Open
和 db.Ping
初始化数据库连接池。
- handleRequest 函数:使用互斥锁保护对共享数据结构的操作,从连接池获取数据库连接并执行数据库操作。
- main 函数:模拟多个请求,每个请求在一个新的 goroutine 中处理,并通过
sync.WaitGroup
等待所有请求处理完毕。