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.

Reply via email to