是删除保证从golang中的哈希中删除?

时间:2016-10-06 22:07:48

标签: go

我有这样的哈希:

  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中。这怎么可能?

1 个答案:

答案 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频道上传递增量和减量。