zinx
zinx copied to clipboard
有个疑问,这种情况需要加锁吗?
func (m *Move) Handle (request ziface.IRequest){ //1 解析客户端传递过来的protobuf protoMsg := &pb.Position{} err := proto.Unmarshal(request.GetData(), protoMsg) if err != nil { fmt.Printf("move router proto unmarshal error:%v\n",err) return } //2 得到当前发送位置的是哪个玩家 pid, err := request.GetConnection().GetProperty("pid") if err != nil { fmt.Printf("move router get pid error:%v\n",err) return }
//3 获取player对象
player := core.WorldMgrObj.GetPlayerByPid(pid.(int32))
//4 广播并更新当前玩家的位置
player.UpdatePos(protoMsg.X ,protoMsg.Y, protoMsg.Z, protoMsg.V)
} 您好 ,我有个疑问,想第3步获取了player对象,这个时候修改player对象需要加锁吗 ,我理解是需要加锁的,因为在此时可能有其他协程在读取player对象的数据,这个时候我们修改player,可能会造成数据竞争,请问是有这个问题吗?
GetPlayerByPid(pid.(int32))
这个func:
func (wm *WorldManager) GetPlayerByPid(pid int32) *Player {
wm.pLock.RLock()
defer wm.pLock.RUnlock()
return wm.Players[pid]
}
在world_manager.go里面看到所有关于player 的操作都是加锁的,在重写Handle这个方法里,不要进行任何加解锁的操作,我理解为没有在一个操作层面里面。
//马上以非阻塞方式处理消息
func (mh *MsgHandle) DoMsgHandler(request ziface.IRequest) {
handler, ok := mh.Apis[request.GetMsgID()]
if !ok {
fmt.Println("api msgId = ", request.GetMsgID(), " is not FOUND!")
return
}
//执行对应处理方法
handler.PreHandle(request)
handler.Handle(request)
handler.PostHandle(request)
}