Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
520akyi opened this issue Feb 14, 2020 · 1 comment
Open

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

520akyi opened this issue Feb 14, 2020 · 1 comment

Comments

@520akyi
Copy link

520akyi commented Feb 14, 2020

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

@adsian
Copy link
Collaborator

adsian commented Feb 22, 2020

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)

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants