gpt4 book ai didi

go - 我怎样才能摆脱这种数据竞争

转载 作者:IT王子 更新时间:2023-10-29 02:15:12 24 4
gpt4 key购买 nike

我有这两个功能:

// PartyHub struct contains all data for the party
type PartyHub struct {
FullPartys map[string]Party
PartialPartys map[string]Party
Enter chan Member
Leave chan Member
sync.Mutex
}


// RemoveFromQueue will remove the member from party
func (p *PartyHub) RemoveFromQueue(memberLeaving Member, inQueue bool) {
if !inQueue {
return
}
for _, party := range p.PartialPartys {
go func(party Party) {
if _, ok := party.Members[memberLeaving.Identifier]; ok {
p.Lock()
->>>>>>>> delete(party.Members, memberLeaving.Identifier)
p.Unlock()
}
}(party)
}
log.Println("Removing")
}

// SortIntoParty will sort the member into party
func (p *PartyHub) SortIntoParty(newMember Member, inQueue bool) {
log.Println(inQueue)
if inQueue {
return
}
log.Println("Adding")
foundParty := false
->> for partyid, party := range p.PartialPartys {
if !party.Accepting {
continue
}

goodFitForParty := true
for _, partyMember := range party.Members {
if newMember.Type == partyMember.Type && newMember.Rank >= partyMember.Rank-partyMember.RankTol && newMember.Rank <= partyMember.Rank+partyMember.RankTol {
goodFitForParty = true
continue
} else {
goodFitForParty = false
break
}
}

if !goodFitForParty {
continue
} else {
foundParty = true
newMember.Conn.CurrentParty = partyid
p.Lock()
p.PartialPartys[partyid].Members[newMember.Conn.Identifier] = newMember
p.Unlock()
if len(party.Members) == 2 {
p.Lock()
party.Accepting = false
p.Unlock()
// Start Go Routine
}
break
}
}
if !foundParty {
uuid := feeds.NewUUID().String()
newMember.Conn.CurrentParty = uuid
p.Lock()
p.PartialPartys[uuid] = Party{Accepting: true, Members: make(map[string]Member), Ready: make(chan *Connection), Decline: make(chan *Connection)}
p.PartialPartys[uuid].Members[newMember.Conn.Identifier] = newMember
p.Unlock()
}
}

我将 ->>>>>> 放在访问 2 段代码的位置旁边,我不确定如何在不在数据中的情况下使这 2 段保持最新种族,相当新,想知道我应该如何在没有数据竞争的情况下读写这个变量。

最佳答案

你的问题中有很多代码,但看起来你正试图从一个 goroutine 中的 map (party.Members) 中删除元素,同时循环遍历它其他。这听起来像是一场无法维护、错误百出的灾难,但没有内存竞争是可能的。

您需要一个互斥锁来保护对 map 的访问(读取和写入),而困难的部分是确保在 for/range 迭代期间保持锁定。这是一种方法,在 for 循环开始之前持有锁,然后在循环体内解锁。

var mut sync.Mutex
var m = map[string]int{}

func f(key string) {
mut.Lock()
defer mut.Unlock()
delete(m, key)
}

func g() {
mut.Lock()
defer mut.Unlock()
for k, v := range m {
mut.Unlock()
fmt.Println(k, v)
mut.Lock()
}
}

在这里,可以同时调用 fg 的任意组合,而不会发生内存竞争。

更容易理解的是不解锁/锁定循环内的互斥量,这意味着 f 中的删除将等待 g 中的任何正在运行的循环完成(或反之亦然)。

关于go - 我怎样才能摆脱这种数据竞争,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34469080/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com