我正在处理goroutine中的一些用户会话数据并创建地图以跟踪用户ID - >里面的会话数据。 goroutine遍历切片,如果找到SessionEnd事件,则在同一次迭代中删除映射键。这似乎并非总是如此,因为我仍然可以在以下迭代中检索一些数据以及“key exists”bool变量。就好像某些变量尚未归零。
每张地图只有一个goroutine写/读它。从我的理解,不应该有一个竞争条件,但它肯定似乎有map和delete()。
如果每次迭代都运行垃圾收集器,代码工作正常。我是否将地图用于错误的用途?
伪代码(在单个goroutine中运行的函数,行作为变量传递):
active := make(ActiveSessions) // map[int]UserSession
for _, l := range lines { // lines is a slice of a parsed log
u = l.EventData.(parser.User)
s, exists = active[u.SessionID]
switch l.Event {
// Contains cases which can check if exists is true or false
// errors if contains an event that can't happen,
// for example UserDisconnect before UserConnect,
// or UserConnect while a session is already active
case "UserConnect":
if exists {
// error, can't occur
// The same session id can occur in the log after a prior session has completed,
// which is exactly when the problems occur
}
case "UserDisconnect":
sessionFinished = true
}
// ...
if sessionFinished {
// <add session to finished sessions>
delete(active, u.SessionID)
// Code works only if runtime.GC() is executed here, could just be a coincidence
}
}