2016-10-06 3 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常にどちらかの作品、またはERRを持っていますが、スタックトレース例外をスローしないとラインので、プログラム全体をクラッシュしない:

delete(TransfersInFlight, timeKey) 

は時間の100%を呼び出さなければなりません。それでも、この行が呼び出されず、TransfersInFlightにファイルが永遠に残っているような場合があります。これはどのように可能ですか?

+2

マップに複数の場所で同時にアクセスしていますか?レースディテクタでコードを実行します。 – JimB

+0

ああ、私はミューテックスが必要ですか?私はgolangがそれのようにハッシュに原子操作を持っていると思った。 –

+4

私はあなたが何を意味しているのかはわかりませんが、Goの_no_値は並行読み書きには安全です。唯一の「アトミック」操作は、「同期/アトミック」パッケージです。 – JimB

答えて

1

地図は並行アクセスでは安全ではありません。私はマップアクセスを緩和するためにミューテックスを使うか、あるいは "op"構造体のチャンネルを読み込んだり、 "add"チャンネルと "delete"チャンネルを持っているゴルーチンを持っています。

複数の読み取り専用アクセスを同時に行うことは安全ですが、一度書き込みを行うと、一度に1つしかアクセスできないようにしてください。

あなたは、カウントを管理するためにゴルーチンを使用して設定されている場合、一つの方法は、のようになります。

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

関連する問題