2016-10-06 64 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