3 ms·
What should the code be instead?
by _sdegutis 8y ago
What should the code be instead?
- TheDong 8y agoThere are many possible fixes. The most obvious is to wrap it in a mutex (assuming 'done' is standing in for much more complex logic): func main() { doneMutex := sync.Mutex{} done := false go func(){ doneMutex.Lock() defer doneMutex.Unlock() done = true }() getDone := func() bool { doneMutex.Lock() defer doneMutex.Unlock() return done } for !getDone() { runtime.Gosched() } fmt.Println("done!") } Another option would be to use a channel in place of done. Effectively, the lesson here is that go doesn't have concurrently safe types (e.g. no concurrent map) nor generics to create them, so all concurrent code must be built around the builtin generic concurrent-safe type (channels) or must make careful use of mutexes / the atomic package / etc. Idiomatic concurrent go either is built around channels or mutexes, and in either case the compiler won't tell you if you messed up, only the runtime race detector and testing will save you.
- gophergopher 8y agoVersion 1.9 introduced the sync.Map https://golang.org/pkg/sync/#Map https://golang.org/pkg/sync/#Map Would using a sync.WaitGroup and closure be wrong? Is mutex better for shared memory?
- jzelinskie 8y agosync.Map is NOT a good solution for all concurrent map use cases. Please use your best judgement for the well documented trade-offs: >The Map type is optimized for two common use cases: (1) when the entry for a given key is only ever written once but read many times, as in caches that only grow, or (2) when multiple goroutines read, write, and overwrite entries for disjoint sets of keys. In these two cases, use of a Map may significantly reduce lock contention compared to a Go map paired with a separate Mutex or RWMutex.
- raphlinus 8y agoThe fix that's probably closest to the author's intent is to use an atomic. There's no atomic boolean in the language, but if you store 0 or 1 in an int32 it works.
- kodablah 8y agoA single-item-buffered chan is probably most common, but a sync.WaitGroup w/ a 1 add can work if you don't need to do other ops while waiting.