zinx icon indicating copy to clipboard operation
zinx copied to clipboard

有个疑问,这种情况需要加锁吗?

Open 520akyi opened this issue 5 years ago • 1 comments

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,可能会造成数据竞争,请问是有这个问题吗?

520akyi avatar Feb 14 '20 11:02 520akyi

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)

}

adsian avatar Feb 22 '20 05:02 adsian