我有这样的哈希:
var TransfersInFlight map[string]string = make(map[string]string)
在我发送文件之前,我为它存储了一个密钥,发送它,删除它:
timeKey := fmt.Sprintf("%v",time.Now().UnixNano())
TransfersInFlight[timeKey] = filename
total, err := sendTheFile(filename)
delete(TransfersInFlight, timeKey)
即。在发送文件所花费的时间内,哈希中有一个带有时间戳指向文件名的密钥。
func sendTheFile
总是工作,或者有错误但从不抛出堆栈跟踪异常并崩溃整个程序,所以行:
delete(TransfersInFlight, timeKey)
应该100%被召唤。然而,我有时会发现这样的情况,就是这条线从未被调用过,文件永远停留在TransfersInFlight中。这怎么可能?
答案 0 :(得分:1)
地图对于并发访问不安全。我会使用互斥锁来调节地图访问权限,或者使用goroutine读取" op"结构或有一个"添加"频道和"删除"信道。
您可能同时安全地进行多次只读访问,但是一旦您在混合中进行了写入操作,您确实希望确保一次只能访问一次。
如果您开始使用goroutine来管理计数,则可以采用以下方式:
import "sync/atomic"
var TransferChan chan int32
var TransfersInFlight int32
func TransferManager() {
TransfersInFlight = 0
for delta := range TransferChan {
// You're *probably* safe just using +=, but, you know...
atomic.AddInt32(&TransfersInFlight, delta)
}
}
这样,您只需要执行go TransferManager()
,然后在TransferChan
频道上传递增量和减量。