Good to know about not needing sync/atomic. I used a pointer to an externally defined mutex because an answer I found on StackOverflow recommended doing that. However, on looking at my application more closely I think you're right about putting it inside the struct.
On Sunday, April 14, 2019 at 2:16:11 PM UTC-4, Matt Harden wrote: > > No, you don't need sync/atomic. The mutex is sufficient. By the way, you > should put the mutex inside of guardedState, next to the data being > guarded. Had you done that originally, Go Vet would have complained about > you passing guardedState by value (mutexes should never by copied). > > https://play.golang.org/p/yuYjhSzdBoQ > > > On Sun, Apr 14, 2019 at 9:51 AM <michae...@gmail.com <javascript:>> wrote: > >> Thanks, Skip. That fixes it. Is the need for a pointer receiver >> documented somewhere? It's not something that even crossed my mind given >> that the neither the compiler nor golint complained. I suppose it makes >> sense if I think of func (x) foo(y) {} as being an alternate way of writing >> func foo(x, y) {}. In that case, it's clear that a copy of x is being >> passed since that's Go's default. >> >> While this topic is still alive, I'd like to ask a follow-on question: Is >> the use of sync/atomic actually needed in this example or is it sufficient >> to wrap all accesses in mutex Lock/Unlock (using the same mutex, of course). >> >> >> >> On Sunday, April 14, 2019 at 12:08:55 PM UTC-4, Skip wrote: >>> >>> The receiver for load and update should be the original object not a >>> copy. >>> >>> https://play.golang.org/p/XCZC0OVhGMa >>> >>> On Sun, Apr 14, 2019, 7:56 AM <michae...@gmail.com> wrote: >>> >>>> >>>> https://play.golang.org/p/6aQYNjojyBD >>>> >>>> I'm clearly missing something about the way sync.Mutex and atomic.Value >>>> work in Go. >>>> >>>> I'm attempting to write a pair of concurrency safe methods, load() and >>>> update(), for accessing a struct. The struct is stored as an atomic.Value >>>> and accessed with atomic.Load and atomic.Value. I'm also wrapping the >>>> accesses within a mutex Lock/Unlock. That's probably unneeded for my >>>> load() method but I added it trying to figure out why it's not returning >>>> updated info. In my minimal example below (also in the Go Playground link >>>> above) the output of main() should be: >>>> >>>> s={65535} >>>> v={65535} >>>> >>>> but I get >>>> >>>> s={65535} >>>> v={0} >>>> >>>> indicating that the updated value is not available after the call to >>>> update(). >>>> >>>> The only thing I'm doing that's a little different from the examples in >>>> the doc for sync/atomic is passing a function that takes a pointer to a >>>> struct instance to my update function. I do that to make it easy to write >>>> code that updates just a few items in the state struct (which in my real >>>> application has many members instead of just one as shown here.) >>>> >>>> Apologies for wasting the group's time if I've overlooked a brain-dead >>>> error, but I've been fooling with this for several hours now and can't see >>>> why it shouldn't be working, >>>> >>>> >>>> package main >>>> >>>> import ( >>>> "fmt" >>>> "sync" >>>> "sync/atomic" >>>> ) >>>> >>>> type state struct { >>>> R4000 uint16 >>>> } >>>> type guardedState struct { >>>> v atomic.Value >>>> } >>>> >>>> var stateMutex = sync.Mutex{} >>>> var gState guardedState >>>> >>>> func init() { >>>> gState.v.Store(state{}) >>>> } >>>> >>>> func (g guardedState) load() state { >>>> stateMutex.Lock() >>>> defer stateMutex.Unlock() >>>> s := gState.v.Load() >>>> return s.(state) >>>> } >>>> >>>> func (g guardedState) update(f func(*state)) { >>>> stateMutex.Lock() >>>> defer stateMutex.Unlock() >>>> s := g.v.Load().(state) >>>> f(&s) >>>> g.v.Store(s) >>>> } >>>> >>>> func main() { >>>> f := func(s *state) { >>>> s.R4000 = 65535 >>>> fmt.Printf("s=%v\n", *s) >>>> } >>>> gState.update(f) >>>> v := gState.load() >>>> fmt.Printf("v=%v\n", v) >>>> } >>>> >>>> -- >>>> You received this message because you are subscribed to the Google >>>> Groups "golang-nuts" group. >>>> To unsubscribe from this group and stop receiving emails from it, send >>>> an email to golan...@googlegroups.com. >>>> For more options, visit https://groups.google.com/d/optout. >>>> >>> -- >> You received this message because you are subscribed to the Google Groups >> "golang-nuts" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to golan...@googlegroups.com <javascript:>. >> For more options, visit https://groups.google.com/d/optout. >> > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.