2016-10-06 62 views
-1

我有这样一个哈希:在需要的时间是否删除保证从golang中的哈希中删除?

timeKey := fmt.Sprintf("%v",time.Now().UnixNano()) 
    TransfersInFlight[timeKey] = filename 
    total, err := sendTheFile(filename) 
    delete(TransfersInFlight, timeKey) 

即:

var TransfersInFlight map[string]string = make(map[string]string) 

而且之前我发送一个文件我做一个键就存储,发送和删除它发送文件,散列中有一个关键字,指向文件名的时间戳。

的FUNC sendTheFile往往不是作品,或有犯错,但从来没有抛出一个异常堆栈异常和崩溃的整个程序太行:

delete(TransfersInFlight, timeKey) 

应该叫做时间的100%。然而,我有时会发现这样的情况,就像这条线从未被调用过,并且文件永远卡在TransfersInFlight中。这怎么可能?

+2

您是否同时访问多个地方的地图?用赛跑探测器运行你的代码。 – JimB

+0

哦,我只需要一个互斥锁?我认为golang有这样的哈希原子操作。 –

+4

我不确定你的意思,但Go中的_no_值对于并发读写是安全的。唯一的“原子”操作是通过“sync/atomic”包。 – JimB

回答

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渠道。

+0

感谢陈和操作的想法。这是一个好主意。使代码更简单。 –

+0

@AndrewArrow我冒昧地用行内代码替换你的图像。 – Vatine