私は次のようなゴルーチンを持っています。時には恐ろしい "致命的なエラー:同時マップ読み取りとマップ書き込み"が発生します。トレースバックは、s:= db.FileInfo ...マップ参照でそのことを示します。golang mutexが動作することがありますか?
func HMAC(source string, i int) {
var value [4]byte
var mutex sync.Mutex
defer WG.Done()
hash, err := HashString(source);
if err != nil {
log.Critical("HashString error: ",err)
}
log.Trace("Slice:",i,"Authentication hash =",hash)
rand.Seed(time.Now().UnixNano())
mutex.Lock() // Protect Map activity
defer mutex.Unlock()
s := db.FileInfo.Slices[SliceName]
s.Block[i].HMAC = hash
for j:=0; j<32; j++ {
off := rand.Intn(DataLen-5) // 4 should do, but be safe
s.Block[i].Random[j].Offset = off
for k:=0; k<4; k++ {
value[k] = source[off+k]
}
s.Block[i].Random[j].Value = value
}
db.FileInfo.Slices[SliceName] = s
}
HashString(ソース)関数は計算集約的なので、ゴルーチンとしては適切です。ミューテックス呼び出しの後のコードは、すべて計算的に比較的簡単で、HashString(ソース)呼び出しにかかる時間の1%未満を占めます。獣医はルーチンとその呼び出し元できれいです。
util.WG.Add(32)
for i:=0; i<32; i++ {
off := i*util.BlockLen
go util.HMAC(string(tblock[off:off+util.BlockLen-1]),i)
}
util.WG.Wait()
私は非常にinconsistantly、プログラムのすべての半ダースかそこらの呼び出しの外に一回程度のエラーが表示されます。次のように
この関数は、(32)回と呼ばれています。
誰かが私が間違っていることを察知していますか?この問題の時折、私は困惑しています。ああ、FWIW、12スレッドI7で動作している。また:行くバージョンgo1.7.5 linux/amd64。
ありがとうございますAndy。それは私が夜のために置いた後約20秒に起こった... – Cassey