diff --git a/src/server/game/champship_mgr.go b/src/server/game/champship_mgr.go index 1e5d048d..d133aab3 100644 --- a/src/server/game/champship_mgr.go +++ b/src/server/game/champship_mgr.go @@ -11,6 +11,7 @@ import ( proto "server/msg" "server/pkg/github.com/name5566/leaf/log" "sort" + "sync" "time" ) @@ -23,6 +24,7 @@ type ChampshipMgr struct { } type ChampshipData struct { + mu sync.RWMutex AutoId int RobotId int Rank map[int][]*ChampshipRank // 锦标赛排行榜 @@ -115,7 +117,7 @@ func (c *ChampshipMgr) NotifyAll() (interface{}, error) { func (c *ChampshipMgr) ZeroUpdate() (interface{}, error) { log.Debug("ChampshipMgr ZeroUpdate") data := c.getData() - c.lock.Lock() + data.mu.Lock() data.ZeroTime = GoUtil.ZeroTimestamp() // 深拷贝 map,避免多个协程持有同一个 map 引用导致并发读写 oldRank := make(map[int][]*ChampshipRank, len(data.Rank)) @@ -144,7 +146,7 @@ func (c *ChampshipMgr) ZeroUpdate() (interface{}, error) { for k := range data.PreGroupInfo { c.SetRankCache(k) } - c.lock.Unlock() + data.mu.Unlock() c.mDispatr.AfterFunc(time.Duration(GoUtil.NextZeroTimestampDuration())*time.Second, func() { c.ZeroUpdate() @@ -159,7 +161,7 @@ func (c *ChampshipMgr) ZeroUpdate() (interface{}, error) { func (c *ChampshipMgr) NotifyPlayer() { data := c.getData() - c.lock.Lock() + data.mu.RLock() // 深拷贝需要通知的数据,避免在锁外访问 map notifyList := make([]struct { Uid int @@ -176,7 +178,7 @@ func (c *ChampshipMgr) NotifyPlayer() { }{Uid: v[i].Uid, Rank: i + 1}) } } - c.lock.Unlock() + data.mu.RUnlock() // 在锁外通知,避免持锁时间过长 for _, item := range notifyList { @@ -186,8 +188,8 @@ func (c *ChampshipMgr) NotifyPlayer() { func (c *ChampshipMgr) ai() (interface{}, error) { ChampshipData := c.getData() - c.lock.Lock() - defer c.lock.Unlock() + ChampshipData.mu.Lock() + defer ChampshipData.mu.Unlock() Now := GoUtil.Now() uids := make(map[int]struct{}) for k, v := range ChampshipData.Rank { @@ -248,8 +250,8 @@ func (c *ChampshipMgr) ai() (interface{}, error) { func (c *ChampshipMgr) GetPreRankMsg(Uid int) *proto.ResChampshipPreRank { ChampshipData := c.getData() - c.lock.Lock() - defer c.lock.Unlock() + ChampshipData.mu.RLock() + defer ChampshipData.mu.RUnlock() GroupId := ChampshipData.PreGroupInfo[Uid] if GroupId == 0 { return &proto.ResChampshipPreRank{} @@ -306,8 +308,8 @@ func (c *ChampshipMgr) GetPreRankMsg(Uid int) *proto.ResChampshipPreRank { // TODO 待优化 func (c *ChampshipMgr) GetRankMsg(Uid int) *proto.ResChampshipRank { ChampshipData := c.getData() - c.lock.Lock() - defer c.lock.Unlock() + ChampshipData.mu.RLock() + defer ChampshipData.mu.RUnlock() GroupId := ChampshipData.GroupInfo[Uid] if GroupId == 0 { return &proto.ResChampshipRank{} @@ -371,8 +373,8 @@ func (c *ChampshipMgr) group() (interface{}, error) { return nil, nil } ChampshipData := c.getData() - c.lock.Lock() - defer c.lock.Unlock() + ChampshipData.mu.Lock() + defer ChampshipData.mu.Unlock() if len(ChampshipData.Pool) == 0 { // 未分配玩家池为空 return nil, nil } @@ -468,8 +470,8 @@ func (c *ChampshipMgr) group() (interface{}, error) { func (c *ChampshipMgr) getGroupId(Uid int) int { ChampshipData := c.getData() - c.lock.Lock() - defer c.lock.Unlock() + ChampshipData.mu.RLock() + defer ChampshipData.mu.RUnlock() GroupId, ok := ChampshipData.GroupInfo[Uid] if ok { return GroupId @@ -484,8 +486,8 @@ func (c *ChampshipMgr) inRank(m *msg.Msg) (interface{}, error) { GroupId := c.getGroupId(data.Uid) ChampshipData := c.getData() - c.lock.Lock() - defer c.lock.Unlock() + ChampshipData.mu.Lock() + defer ChampshipData.mu.Unlock() // 再次检查 GroupId,因为可能在等待锁期间被其他协程修改 if currentGroupId, ok := ChampshipData.GroupInfo[data.Uid]; ok { @@ -557,8 +559,8 @@ func (c *ChampshipMgr) inRank(m *msg.Msg) (interface{}, error) { func (c *ChampshipMgr) getMyRank(Uid int) int { ChampshipData := c.getData() - c.lock.Lock() - defer c.lock.Unlock() + ChampshipData.mu.RLock() + defer ChampshipData.mu.RUnlock() GroupId := ChampshipData.GroupInfo[Uid] if GroupId == 0 { return 0 @@ -595,8 +597,8 @@ func (c *ChampshipMgr) unsafe_getMyRank(Uid int) int { func (c *ChampshipMgr) getLastMyRank(Uid int) int { ChampshipData := c.getData() - c.lock.Lock() - defer c.lock.Unlock() + ChampshipData.mu.RLock() + defer ChampshipData.mu.RUnlock() GroupId := ChampshipData.PreGroupInfo[Uid] if GroupId == 0 { return 0 diff --git a/src/server/game/message_mgr.go b/src/server/game/message_mgr.go index c010525e..6fd4d5b1 100644 --- a/src/server/game/message_mgr.go +++ b/src/server/game/message_mgr.go @@ -49,6 +49,7 @@ type MessageMgr struct { type MessageData struct { MessageList map[int64]*MessageList PlayerList map[int64]int + mu sync.Mutex } type MessageList struct { @@ -131,8 +132,8 @@ func (m *MessageMgr) MessageMgrInit() { func FixBug() { messageMgrData := getMessageData() // 先更新 PlayerList(需要加锁) - G_GameLogicPtr.MessageMgr.lock.Lock() - defer G_GameLogicPtr.MessageMgr.lock.Unlock() + messageMgrData.mu.Lock() + defer messageMgrData.mu.Unlock() now := GoUtil.Now() for k, v := range messageMgrData.MessageList { if k < 100000 { @@ -214,12 +215,12 @@ func ChampshipRankInfoHandler(data *msg.Msg) (interface{}, error) { func NotifyAllPlayerMsg(m *msg.Msg) { messageMgrData := getMessageData() // 先复制 PlayerList,避免长时间持有锁 - G_GameLogicPtr.MessageMgr.lock.Lock() + messageMgrData.mu.Lock() playerListCopy := make(map[int64]int, len(messageMgrData.PlayerList)) for k, v := range messageMgrData.PlayerList { playerListCopy[k] = v } - G_GameLogicPtr.MessageMgr.lock.Unlock() + messageMgrData.mu.Unlock() // 在锁外发送消息 for PlayerId, node := range playerListCopy { @@ -249,9 +250,9 @@ func CatnipPartnerHandler(data *msg.Msg) (interface{}, error) { func ReplyPlayerMsgASync(m *msg.Msg, reply interface{}) (interface{}, error) { clone := m.Reply(reply) messageMgrData := getMessageData() - G_GameLogicPtr.MessageMgr.lock.Lock() + messageMgrData.mu.Lock() node, ok := messageMgrData.PlayerList[int64(m.From)] - G_GameLogicPtr.MessageMgr.lock.Unlock() + messageMgrData.mu.Unlock() if ok { SendMsgToNodeAsync(clone, node) @@ -272,10 +273,10 @@ func ClusterSyncHandler(data *msg.Msg) (interface{}, error) { }) // 发送暂存区消息(先复制再释放锁,避免长时间持有锁) messageMgrData := getMessageData() - G_GameLogicPtr.MessageMgr.lock.Lock() + messageMgrData.mu.Lock() TempMessageList := messageMgrData.MessageList messageMgrData.MessageList = make(map[int64]*MessageList) - G_GameLogicPtr.MessageMgr.lock.Unlock() // 立即释放锁,在锁外发送消息 + messageMgrData.mu.Unlock() // 立即释放锁,在锁外发送消息 log.Debug("[Middleware] Cluster sync send temp message len: %d", len(TempMessageList)) for _, Message := range TempMessageList { @@ -291,9 +292,9 @@ func PlayerLoginHandler(data *msg.Msg) (interface{}, error) { node := data.Extra.(int) messageMgrData := getMessageData() // 先更新 PlayerList(需要加锁) - G_GameLogicPtr.MessageMgr.lock.Lock() + messageMgrData.mu.Lock() messageMgrData.PlayerList[int64(data.From)] = node - G_GameLogicPtr.MessageMgr.lock.Unlock() + messageMgrData.mu.Unlock() log.Debug("[Middleware] Player login success player id: %v, node: %v", data.From, data.Extra.(int)) // 对玩家消息列表加锁 @@ -331,9 +332,9 @@ func PlayerLoginHandler(data *msg.Msg) (interface{}, error) { func PlayerLogoutHandler(data *msg.Msg) (interface{}, error) { messageMgrData := getMessageData() - G_GameLogicPtr.MessageMgr.lock.Lock() + messageMgrData.mu.Lock() delete(messageMgrData.PlayerList, int64(data.From)) - G_GameLogicPtr.MessageMgr.lock.Unlock() + messageMgrData.mu.Unlock() log.Debug("[Middleware] Player logout success player id: %v", data.From) return nil, nil } @@ -359,9 +360,9 @@ func ComsumerMsgHandler(data *msg.Msg) (interface{}, error) { func NotifyPlayerMsgAsync(m *msg.Msg) { messageMgrData := getMessageData() // 检查玩家是否在线(需要加锁) - G_GameLogicPtr.MessageMgr.lock.Lock() + messageMgrData.mu.Lock() node, ok := messageMgrData.PlayerList[int64(m.To)] - G_GameLogicPtr.MessageMgr.lock.Unlock() + messageMgrData.mu.Unlock() // 在线则直接发送消息 if ok { SendMsgToNodeAsync(m, node) @@ -375,9 +376,9 @@ func CenterPlayerMsgHandler(data *msg.Msg) (interface{}, error) { // 遍历消息列表,发送消息给在线玩家 // 检查玩家是否在线(需要加锁) - G_GameLogicPtr.MessageMgr.lock.Lock() + messageMgrData.mu.Lock() node, ok := messageMgrData.PlayerList[int64(PlayerId)] - G_GameLogicPtr.MessageMgr.lock.Unlock() + messageMgrData.mu.Unlock() // 在线则直接发送消息 if ok { SendMsgToNodeAsync(data, node) @@ -885,8 +886,9 @@ func sendMessageSync(m *msg.Msg, node int) (*msg.Msg, error) { // 保存消息到本地 func saveMessage(m *msg.Msg) error { - G_GameLogicPtr.MessageMgr.lock.Lock() - defer G_GameLogicPtr.MessageMgr.lock.Unlock() + data := getMessageData() + data.mu.Lock() + defer data.mu.Unlock() // 使用不加锁的内部方法,避免死锁 messages := getMessgeUnsafe(int64(m.To)) messages.mu.Lock() @@ -933,8 +935,9 @@ func getMessgeUnsafe(PlayerId int64) *MessageList { // getMessge 获取消息列表(加锁版本) func getMessge(PlayerId int64) *MessageList { - G_GameLogicPtr.MessageMgr.lock.Lock() - defer G_GameLogicPtr.MessageMgr.lock.Unlock() + messageMgrData := getMessageData() + messageMgrData.mu.Lock() + defer messageMgrData.mu.Unlock() return getMessgeUnsafe(PlayerId) } @@ -968,8 +971,8 @@ func deleteMessage(m *msg.Msg) error { if len(messages.Messages) == 0 { // 如果消息列表为空,则删除该玩家的消息列表 messageMgrData := getMessageData() - G_GameLogicPtr.MessageMgr.lock.Lock() - defer G_GameLogicPtr.MessageMgr.lock.Unlock() + messageMgrData.mu.Lock() + defer messageMgrData.mu.Unlock() delete(messageMgrData.MessageList, int64(m.To)) } return nil diff --git a/src/server/game/server_mod.go b/src/server/game/server_mod.go index fc55e6e1..cddcee79 100644 --- a/src/server/game/server_mod.go +++ b/src/server/game/server_mod.go @@ -139,9 +139,7 @@ func (s *ServerMod) SaveData() { DbData.Key = s.key DbData.UpdataTime = GoUtil.Now() var err error - s.lock.Lock() DbData.ModData, err = GoUtil.GobMarshal(s.data) - s.lock.Unlock() if err != nil { log.Error("SaveData Marshal failed,Mod Key: %s err:%v", s.key, err) return diff --git a/src/server/game/var_mgr.go b/src/server/game/var_mgr.go index a2bc5f1b..ee2b5ed2 100644 --- a/src/server/game/var_mgr.go +++ b/src/server/game/var_mgr.go @@ -7,6 +7,7 @@ import ( "server/game/mod/msg" GoUtil "server/game_util" "strings" + "sync" "time" ) @@ -23,6 +24,7 @@ type VarData struct { NewUseVar map[int]map[string]*VarExpireData ZeroTime int64 Version int64 + mu sync.Mutex } const ( @@ -64,8 +66,8 @@ func (f *VarMgr) Init() { func (f *VarMgr) fixbug() { data := f.getData() - f.lock.Lock() - defer f.lock.Unlock() + data.mu.Lock() + defer data.mu.Unlock() for k, v := range data.NewUseVar { if v != nil { del := true @@ -87,8 +89,8 @@ func (f *VarMgr) version() { case 0: // future version update data := f.getData() - f.lock.Lock() - defer f.lock.Unlock() + data.mu.Lock() + defer data.mu.Unlock() // set to next version for k, v := range data.UserVar { if v != nil { @@ -127,8 +129,9 @@ func (f *VarMgr) ZeroUpdate() { } func (f *VarMgr) HandleCatnipPartner(Uid, Partner, GameId int, EndTime int64) (interface{}, error) { - f.lock.Lock() - defer f.lock.Unlock() + data := f.getData() + data.mu.Lock() + defer data.mu.Unlock() OtherPartnerInfo := f.GetUserVar(Uid, VAR_CATNIP_PARTNER) MyPartnerInfo := f.GetUserVar(Partner, VAR_CATNIP_PARTNER) @@ -149,8 +152,6 @@ func (f *VarMgr) HandleCatnipPartner(Uid, Partner, GameId int, EndTime int64) (i } func (f *VarMgr) SetUserVar(uid int, key string, value interface{}) { - f.lock.Lock() - defer f.lock.Unlock() varData := f.getData().NewUseVar[uid] if varData == nil { varData = make(map[string]*VarExpireData) @@ -167,8 +168,6 @@ func (f *VarMgr) SetUserVar(uid int, key string, value interface{}) { } func (f *VarMgr) GetUserVar(uid int, key string) *VarExpireData { - f.lock.Lock() - defer f.lock.Unlock() varData := f.getData().NewUseVar[uid] if varData == nil { varData = make(map[string]*VarExpireData) @@ -183,8 +182,6 @@ func (f *VarMgr) GetUserVar(uid int, key string) *VarExpireData { } func (f *VarMgr) SetVar(key string, value interface{}) { - f.lock.Lock() - defer f.lock.Unlock() f.getData().NewVar[key] = &VarExpireData{ D: value, } @@ -201,8 +198,8 @@ func getVarData() *VarData { func SetVarDataHandler(m *msg.Msg) (interface{}, error) { data := getVarData() - G_GameLogicPtr.VarMgr.lock.Lock() - defer G_GameLogicPtr.VarMgr.lock.Unlock() + data.mu.Lock() + defer data.mu.Unlock() if v, ok := m.Extra.(msg.VarData); ok { ved, ok := data.NewVar[v.Key] if !ok { @@ -240,8 +237,8 @@ func SetVarDataHandler(m *msg.Msg) (interface{}, error) { func GetUserVarDataHandler(m *msg.Msg) (interface{}, error) { data := getVarData() - G_GameLogicPtr.VarMgr.lock.Lock() - defer G_GameLogicPtr.VarMgr.lock.Unlock() + data.mu.Lock() + defer data.mu.Unlock() userVar := &VarExpireData{} if v, ok := m.Extra.(msg.VarData); ok { if varData, ok := data.NewUseVar[m.From]; ok { @@ -258,8 +255,8 @@ func GetUserVarDataHandler(m *msg.Msg) (interface{}, error) { func SetUserVarDataHandler(m *msg.Msg) (interface{}, error) { data := getVarData() - G_GameLogicPtr.VarMgr.lock.Lock() - defer G_GameLogicPtr.VarMgr.lock.Unlock() + data.mu.Lock() + defer data.mu.Unlock() if v, ok := m.Extra.(msg.VarData); ok { varData := data.NewUseVar[m.To] if varData == nil { @@ -304,8 +301,6 @@ func SetUserVarDataHandler(m *msg.Msg) (interface{}, error) { func GetVarDataHandler(m *msg.Msg) (interface{}, error) { data := getVarData() - G_GameLogicPtr.VarMgr.lock.Lock() - defer G_GameLogicPtr.VarMgr.lock.Unlock() varData := &VarExpireData{} if v, ok := m.Extra.(msg.VarData); ok { varData, _ = data.NewVar[v.Key]