英文:
Is it safe to be removed from map in a concurrent environment? In Golang
问题
从代码中看,我们需要在删除地图中的项目之前放置锁。在给定的代码中,使用了sync.RWMutex
来实现读写锁。在删除values
地图中的项目时,需要获取写锁。
在给定的代码中,使用了l.RLock()
来获取读锁,然后在for
循环中遍历values
地图。如果value.Error
不为nil
,则需要删除该项目。在删除项目之前,需要获取写锁,然后使用delete(values, key)
删除项目,最后释放写锁。
因此,正确的做法是在删除项目之前获取写锁,然后在删除完成后释放写锁。所以,第4个变体是有效的删除方式,即使用go l.delete(key)
在单独的goroutine中执行删除操作。
英文:
Do I put the lock before removing the item from map?
package main
import (
"errors"
"sync"
"time"
)
type A struct {
Error error
}
func (a *A) Job() {
// ... more job
}
var l sync.RWMutex
func generate() {
l.Lock()
values["key1"] = A{}
l.Unlock()
l.Lock()
values["key2"] = A{}
values["key3"] = A{}
l.Unlock()
// ...
l.Lock()
values["key1919"] = A{Error: errors.New("oh...")}
l.Unlock()
// ...
l.Lock()
values["key99999999999"] = A{}
l.Unlock()
}
var values map[string]A
func main() {
values = make(map[string]A)
go generate()
for {
l.RLock()
for key, value := range values {
if value.Error != nil {
delete(values, key) // it's safe? or you need to take a lock?
} else {
value.Job()
}
}
l.RUnlock()
time.Sleep(10 * time.Second)
}
}
Variants:
-
delete in range without worrying
-
add key in slice and separate range for to remove them
-
l.RUnlock(); l.Lock(); delete(values, key); l.Unlock; l.RLock(); in range
-
go l.delete(key) // gorutin splash
Which variant is the effective removal with lock/unlock?
答案1
得分: 6
从地图中删除被视为写操作,并且必须与所有其他读取和写入操作进行序列化。如果我正确理解了你的问题,那么是的,你需要要么将删除操作批量处理以供稍后执行,要么放弃读取锁并获取写入锁以完成删除操作。
运行时会尝试检测并发的读取和写入操作,并可能导致以下错误之一:
fatal error: concurrent map writes
fatal error: concurrent map read and map write
英文:
Deleting from a map is considered a write operation, and must be serialized with all other reads and writes. If I understand your question correctly, then yes you need to either batch the deletes for later, or give up the read lock and take a write lock to complete the delete.
The runtime attempts to detect concurrent reads and writes, and will crash with one of:
fatal error: concurrent map writes
fatal error: concurrent map read and map write
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论