golang下面代码为什么会死锁
type UserTable struct {
sync.RWMutex
//deadlock.RWMutex
table map[int]string
}
func NewUserTable()*UserTable{
return &UserTable{
table:make(map[int]string),
}
}
func (userTable *UserTable)GetUser(i int)string{
userTable.RLock()
defer userTable.RUnlock()
if name, exist := userTable.table[i]; exist{
return name
}
return ""
}
func (userTable *UserTable)GetTable()map[int]string{
userTable.RLock()
defer userTable.RUnlock()
newMap := make(map[int]string)
for seatID, _ := range userTable.table{
newMap[seatID] = userTable.GetUser(seatID)
}
return newMap
}
func (userTable *UserTable)SetUser(i int, name string){
userTable.Lock()
defer userTable.Unlock()
if len(userTable.table) >= 100{
userTable.table = make(map[int]string)
}
userTable.table[i] = name
}
func main() {
userTable := NewUserTable()
go func() {
i := 0
for{
if i % 1000 == 0{
fmt.Printf("%v\n", userTable.GetTable())
}
userTable.SetUser(i, fmt.Sprintf("%v", i))
i++
}
}()
go func(){
for{
userTable.GetTable()
time.Sleep(100*time.Millisecond)
}
}()
select {
}
//time.Sleep(100* time.Second)
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题在于 GetTable 方法:在该方法中你已经加锁来保护 table 中的数据了,直接操作数据就行了,不应该画蛇添足地调用 GetUser 方法,因为 GetUser 中也要加锁
结果就导致,在第二个 go func 中 GetTable 的两次 RLock 之间,第一个 go func 中的 SetUser 进行 RWLock,此时就会死锁
解决方法很简单,在 GetTable 中直接操作 table,不要再去调用 GetUser 了,
如果从 table 获取值的操作确实在 GetUser 和 GetTable 中都存在,并且较为复杂,你可以再写一个 非导出 的 _help 方法来实现这个功能,这个方法里不要加锁,然后 GetUser 和 GetTable 都调用这个函数